; ; Description: ; 四捨五入つき平方根 ; 距離 ; ; Function: ; int pascal isqrt( long x ) ; ; int pascal ihypot( int x, int y ) ; ; ; Parameters: ; long x ... 平方根を求めたい数 ; 0 <= x < 32767.5↑2 ; ( 0 <= x <= (1073709056 = 3FFF8000h) ) ; これ以外ならばオーバーフロー ; (a↑bはaのb乗の意味) ; ; int x,y ... 距離を得たい座標 ; ; Returns: ; int .......... 0 〜 32767 ; x が 0 またはオーバーフローならば 0 ; ; Requiring Resources: ; CPU: i8086 ; ; Author: ; 恋塚昭彦 ; ; History: ; 92/ 7/31 Initial ; 92/ 8/ 1 ; int ihypot( int x, int y ) ; func IHYPOT push BP mov BP,SP @@y = (RETSIZE+2)*2 @@x = (RETSIZE+1)*2 mov AX,[BP+@@x] imul AX mov BX,AX mov CX,DX mov AX,[BP+@@y] imul AX add BX,AX adc CX,DX jmp short ISQRT_ROOT endfunc ; int pascal isqrt( long x ) ; ; ; 実装:ニュートン法 ; func ISQRT push BP mov BP,SP @@hi = (RETSIZE+2)*2 @@lo = (RETSIZE+1)*2 mov BX,[BP+@@lo] mov CX,[BP+@@hi] ISQRT_ROOT: xor AX,AX ; return code = 0 mov DX,BX or DX,CX jz short @@RETURN ; x = 0 なら return 0 cmp CX,03FFFh ; 0〜3FFF8000hでなければ OverFlow! return 0 ja short @@RETURN jne short @@GO cmp BX,08000h ja short @@RETURN @@GO: push SI shl BX,1 ; CX:BX = x rcl CX,1 shl BX,1 rcl CX,1 ; x *= 4 ; or CX,CX if 0 mov SI,0FFFFh jnz short @@LLOOP mov SI,8 ; SI: y, BP: lasty else jz short @@BXLOOPS mov SI,1 ; 8000h rol 1 mov AX,3 ; 0c000h rol 2 @@CXLOOP: ror SI,1 ror AX,1 ror AX,1 test CX,AX jz short @@CXLOOP or AX,AX jns short @@LLOOP mov SI,0FFFFh ; 最上位bitが立っている場合は overflowを jmp short @@LLOOP ; 防ぐため特例として 0FFFFhを初期値にする @@BXLOOPS: mov SI,100h ; 80h rol 1 mov AX,3 ; 0c000h rol 2 @@BXLOOP: ror SI,1 ror AX,1 ror AX,1 test BX,AX jz short @@BXLOOP ; jmp short LLOOP endif @@LLOOP: mov BP,SI ; lasty = y mov AX,BX mov DX,CX div SI add SI,AX rcr SI,1 ; y = ((unsigned long)x / y + y)/ 2 ; cmp SI,AX je short @@LEXIT cmp SI,BP jne short @@LLOOP ; if ( y != lasty ) goto LLOOP ; @@LEXIT: xor AX,AX shr SI,1 adc AX,SI ; lasty = y & 1 ; return y / 2 + lasty ; pop SI @@RETURN: pop BP ret 4 endfunc