お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"Int32x32To64のインラインasm版"

この発言は
#00788 裏目小僧 さんの線分の上かどうか(多角形)
に対するコメントです

32bitの掛算をして64bitの結果が欲しい場合、DELPHI4 で拡張された INT64に先に変換してから掛算させると64bitの掛算をするために非常に 効率が悪く速度が落ちるようです。 そこで WinAPIの同名の関数をインラインアセンブラで書いてみました。 function Int32x32To64(X, Y: Integer): int64; asm MOV EAX,X {register呼び出し規約の場合はXはEAXなのでホントは不要} IMUL Y end; また、D3を使っていると前回掲示した内外判定や線上判定はTPointを16bit以 上で使っている場合には失敗します。といってINT64はありませんから 以下の ような関数を書いてみました。 以下はD1では使えません D3でテストしています。 {掛算(32x32=64)して引算(64)しその結果が正かゼロか負なら1,0,-1を返す} function MulSubSGN(a,b,c,d:integer):Integer;register;{-a*b + c*d} asm mov eax,a {a=eaxなのでホントは不要} IMUL b {b=edx} xchg c,eax {c=ecx} xchg d,edx {dはregisterでもメモリ} IMUL edx sub eax,c {a*b-c*dに見えるが交換してるので注意} sbb edx,d je @pltest {edxがゼロなら 下位テスト} jge @set1 {edxが正なら 1} mov eax,-1 {edxが負なら-1} jmp @exit @SET1: mov eax,1 jmp @exit @pltest: cmp eax,0 jne @SET1 @exit: end; { (-a*b+c*d)/(b^2+d^2) を計算するのだが (b^2+d^2)をま ともに計算すると遅いので 概算して求めている } function RoughDistance(a,b,c,d:integer):Integer;stdcall;{ (-a*b+c*d)/(b^2+d^2)} asm mov eax,a IMUL b mov a,eax mov ecx,edx mov eax,c IMUL d sub eax,a sbb edx,ecx mov a,eax mov c,edx {b^2+d^2} mov eax,b mov edx,d test eax,eax jns @absskp1 neg eax @absskp1: test edx,edx jns @absskp2 neg edx @absskp2: cmp eax,edx jge @swapSkp xchg eax,edx @swapSkp: shr edx,1 add eax,edx je @exit {ゼロなら割算が出来ない} mov ecx,eax {割算} mov eax,a mov edx,c idiv ecx @exit: end; ---------------------------------------------------------- MulSubSGN は 内外判定 #786 if rx*dy>ry*rdx then inc (ct) else dec(ct); を if MulSubSGN(rx,dy,ry,rdx)< 0 then inc (ct) else dec(ct); と置き換えて使う事が出来ます。 RoughDistance は rx,ry 先の dx,dyの線分までの距離を概算で求める演算 線の上の判定 #788 の dlen:=abs(rx*dy-ry*dx) ; dx:=abs(dx); dy:=abs(dy); if dx>dy then slen:=dx*2+dy else slen:=dy*2+dx; {距離は約2ピクセルに調整しています} if dlen < slen then begin Result:=i; exit; end; {発見した} 以上の5行を if abs(RoughDistance(rx,dy,ry,dx))<2 then begin Result:=i; exit; end; {発見した} と 置き換えて使います。 Original document by 裏目小僧 氏 ID:(GGA03463)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum