function FourNum(s:string):double ; //出現場所 http://piza2.2ch.net/test/read.cgi/tech/995950803/11 var num:double; var sym:char; procedure addsub;forward; procedure next; var i,j:integer; const sep='^+-/*()<>'; begin if s='' then begin sym:=#0;exit;end; for j:=1 to length(sep) do if s[1]=sep[j] then begin sym:=s[1]; delete(s,1,1);s:=trim(s); exit;end ; sym:=#1; for i:=2 to length(s) do for j:=1 to length(sep) do if s[i]=sep[j] then begin num:=StrToFloat(copy(s,1,i-1)); delete(s,1,i-1); exit;end; num:=StrToFloat(s);s:=''; end; procedure factor; begin if(sym = #1) then next else if(sym = '(') then begin next; addsub; if(sym <> ')') then raise Exception.Create(' )がない'); next; end else raise Exception.Create('数があるべき'); end; procedure muldiv; var savenum:double; var oldsym:char; begin factor; while (sym in ['*','/','^'] ) do begin savenum:=num;oldsym:=sym; next; factor; case oldsym of '*': num:=savenum*num; '/': num:=savenum/num; '^': num:=power(savenum,num); end; end; end; procedure addsub; var savenum:double; var oldsym:char; begin case sym of '+': begin next; muldiv; end; '-': begin next; muldiv; num:=-num; end; else muldiv; end; while (sym in [ '+','-'] ) do begin savenum:=num;oldsym:=sym; next; muldiv; case oldsym of '+': num:=savenum+num; '-': num:=savenum-num; end; end; end; begin next; addsub; Result:=num; end;
procedure MkBitRevTbl(n:integer;var tbl:array of integer); var i,j,k,mh,m:integer; begin m :=1 shl n; mh:=m div 2; //mh=msbのみ1のデータ i:=0; // 1単位に増えるアドレス j:=0; // ビット反転アドレス while true do begin tbl[i]:=j; inc(i);if i>=m then break; k:=mh; //mh=msbのみ1のデータ while k<=j do begin //上のビットが立っていたら j:= j and (not k); //それを落としてゆく i-kでも良い筈 k:=k div 2; end; j:= j or k; end; end;
FFTをする為に2のベキで収まる数を求める関数 function iGTexp2(k:integer):integer; //k < 2^n となる 2^n begin k:=k or (k shr 16); //ビットシフトしながらORすると k:=k or (k shr 8); //下位ビットが全部1になる k:=k or (k shr 4); k:=k or (k shr 2); k:=k or (k shr 1); Result:=k+1; //1を足せば 2^nになる end;
function iLog2(m:integer):integer; //m=2^n を与えて nを返す begin if m>=$10000 then Result:=iLog2(m shr 16)+16 else if m>=$100 then Result:=iLog2(m shr 8)+8 else if m>=$10 then Result:=iLog2(m shr 4)+4 else if m>=4 then Result:=iLog2(m shr 2)+2 else if m>=2 then Result:=iLog2(m shr 1)+1 else Result:=0; //1か0 0ならエラーだけど知らない end;
{S〜E の線分と点Pとの距離 } function iSegmentDistance(const S,E,P:TPoint):integer; var pxm,pym,x0m,y0m:integer; begin pxm:=P.x-E.x; pym:=P.y-E.y; x0m:=S.x-E.x; y0m:=S.y-E.y; if MulSubSGN(-x0m,pxm,y0m,pym)<=0 then begin {-a*b + c*d} Result:=iHypot(pxm,pym); end else begin pxm:=P.x-S.x; pym:=P.y-S.y; x0m:=E.x-S.x; y0m:=E.y-S.y; if MulSubSGN(-x0m,pxm,y0m,pym)<=0 then begin Result:=iHypot(pxm,pym); end else begin Result:=ihypot(x0m,y0m); if Result<=0 then Result:= iHypot(pxm,pym) else Result:= abs(MulSubDiv(x0m,pym,y0m,pxm,result)) ; end; end; end;
procedure GetEnumNameList(TypeInfo: PTypeInfo;str:TStrings); var i:integer; var T: PTypeData; var s:string; begin T := GetTypeData(GetTypeData(TypeInfo)^.BaseType^); for i:=T^.MinValue to T^.MaxValue do begin s:= GetEnumName(TypeInfo , i); if s<>'' then str.Add(s) else break; end; end;