2020/08/20(木)22:06
筆算方式で uint32_t の平方根を求める処理 - MO メディアから発掘したコード
MO メディアをサルベージしていたら、懐かしいコードが見つかる。筆算方式で uint32_t (32 bit で表した正の整数) の平方根を求めるコードだ。8086 Assembler のコードで記述してある。アルゴリズムの概要をコメントに書いてあるので他の言語やアセンブラでも容易に書き直せると思う。
idealmodel small,ccodeseg;in A;; X=0; w=0; Count=16; @@l1:; w<<=1; X<<2bit<<A; save X; X-=(w+1); if cond CY; {recover X; }; else; {w|=2;; }; LOOP @@l1;; w>>1 -> ans;in dx:ax;proc NOLANGUAGE sqrrootxor si,si ;bl:si Xxor di,di ;bh:di wmov cx,10hmov bh,0c0hjmp @@l0ineven@@l0:dec cxjz @@exitshl ax,1rcl dx,1shl ax,1rcl dx,1@@l0in:test dh,bhjz @@l0xor bx,bxeven@@l1:shl di,1rcl bh,1shl ax,1rcl dx,1rcl si,1rcl bl,1shl ax,1rcl dx,1rcl si,1rcl bl,1push sipush bxstcsbb si,disbb bl,bhjnb @@j1pop bxpop siloop @@l1shr bh,1rcr di,1mov ax,diret@@j1:add sp,4inc diinc diloop @@l1shr bh,1rcr di,1mov ax,di@@exit:retendpevenpublic ulsqrrootproc ulsqrrootarg @@a:dworduses si,dimov dx,[word high @@a]mov ax,[word low @@a]call sqrrootretendpevenend
コメントのアルゴリズムに対し、実装は上位桁に 0 が続く場合、計算を少し速くする工夫がある。それ以上の変わった処理やアセンブラ独特の高速化は導入していない素朴な処理だ。
今時は浮動小数点計算がお手軽に使えるし、8 ~ 16 bit の組み込みマイクロプロセッサもメーカーが実装例を示しているので、開平処理を態々書くことも無いか。
これをテストするコードは C 言語で書いてあった。分かりやすく書き直してテストしてみる。
ビルドできて、実行すると期待通りの動作をした。Borland C++ 3.1 (TASM, BCC, MAKE, TLINK) でビルドできるソースコード一式を作る。ビット化け、重複、欠落を起こさずに MO から読み出せていた。
今でも懐かしく思えで、動かそうかなと思うコードってそんなに多くないのかな。