flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Reciprocals macro |
Author |
|
idle 23 Jan 2011, 06:55
hi
this is a small revision Tomasz, i think break if condition, and break stopping macro execution, would make a big deal this... Code: ;divisor = 0'000'000'010 mov eax,dividend mov edx,$CCCC'CCCD ;normalized reciprocal(0.099999999860301613 * 2^03) mul edx ;multiply id est divide shr edx,03 ;compensate quotient ;divisor = 0'000'000'009 mov eax,dividend mov edx,$E38E'38E3 ;normalized reciprocal(0.111111111007630825 * 2^03) mul edx ;multiply id est divide shr edx,03 ;compensate quotient ;divisor = 0'000'000'008 mov eax,dividend shr eax,03 ;divisor is power of 2 ;divisor = 0'000'000'007 mov eax,dividend mov edx,$9249'2493 ;normalized reciprocal(0.142857142724096775 * 2^02) mul edx ;multiply id est divide shr edx,02 ;compensate quotient ;divisor = 0'000'000'006 mov eax,dividend mov edx,$AAAA'AAAB ;normalized reciprocal(0.166666666511446237 * 2^02) mul edx ;multiply id est divide shr edx,02 ;compensate quotient ;divisor = 0'000'000'005 mov eax,dividend mov edx,$CCCC'CCCD ;normalized reciprocal(0.199999999953433871 * 2^02) mul edx ;multiply id est divide shr edx,02 ;compensate quotient ;divisor = 0'000'000'004 mov eax,dividend shr eax,02 ;divisor is power of 2 ;divisor = 0'000'000'003 mov eax,dividend mov edx,$AAAA'AAAB ;normalized reciprocal(0.333333333255723118 * 2^01) mul edx ;multiply id est divide shr edx,01 ;compensate quotient ;divisor = 0'000'000'002 mov eax,dividend shr eax,01 ;divisor is power of 2 division by 1 is easy ...is generated by this Code: ; the macro generates constants to replace div by mul ; having questions, mail me to edemko@rambler.ru, or find me at www.board.flatassembler.net ; examples: rcp32 0 ; rcp32 1 ; rcp32 2 ; rcp32 10 ; rcp32 60 ; rcp32 100 ; rcp32 60*60 ; ... macro rcp32 divisor*{ virtual at 0 local dvs dvs = divisor if dvs shr 32 <> 0 display 13, 10, 'divisor must be a 32bit value' err end if if dvs < 2 display 13, 10, 'division by ', dvs + '0', ' is easy' err end if display 13, 10, ' ;divisor = ',\ dvs / 1'000'000'000 + '0',\ '''',\ (dvs / 0'100'000'000) mod 10 + '0',\ (dvs / 0'010'000'000) mod 10 + '0',\ (dvs / 0'001'000'000) mod 10 + '0',\ '''',\ (dvs / 0'000'100'000) mod 10 + '0',\ (dvs / 0'000'010'000) mod 10 + '0',\ (dvs / 0'000'001'000) mod 10 + '0',\ '''',\ (dvs / 0'000'000'100) mod 10 + '0',\ (dvs / 0'000'000'010) mod 10 + '0',\ dvs mod 10 + '0' repeat 31 if dvs = 1 shl % display 13, 10, 'mov eax,dividend',\ 13, 10, 'shr eax,', % / 10 + '0', % mod 10 + '0', ' ;divisor is power of 2 ' dvs = 0 break end if end repeat if dvs <> 0 local dvd, quo, counter, stop_counter? dvd = 1 quo = 0 counter = 0 stop_counter? = 0 repeat 32 + 31 dvd = dvd shl 1 quo = quo shl 1 if dvd >= dvs dvd = dvd - dvs quo = quo + 1 stop_counter? = 1 else if stop_counter? = 0 counter = counter + 1 end if end if end repeat display 13, 10, 'mov eax,dividend',\ 13, 10, 'mov edx,$' dq quo shr 31 quo = quo shl counter shr 31 or 1 repeat 32 / 4 quo = quo shl 4 if quo and $f'0000'0000 > $9'0000'0000 quo = quo + $7'0000'0000 end if display quo shr 32 + '0' quo = quo and $ffff'ffff if % = 4 display '''' end if end repeat display ' ;normalized reciprocal(0.' load quo qword from 0 repeat 18 quo = quo * 10 display quo shr 32 + '0' quo = quo and $ffff'ffff end repeat display ' * 2^', counter / 10 + '0', counter mod 10 + '0', ')',\ 13, 10, 'mul edx ;multiply id est divide ',\ 13, 10, 'shr edx,', counter / 10 + '0', counter mod 10 + '0', ' ;compensate quotient' end if end virtual } count equ 10 rept count var1:0{ display 13,10 rcp32 count-var1 } |
|||
23 Jan 2011, 06:55 |
|
idle 31 Jan 2011, 06:30
this is v3:
- new hex macro - fraction macro supports 64 bit fractions - rounding corrected - set LANG equ ENU to switch from RUS, that's the reason i did not put code directly
|
|||||||||||
31 Jan 2011, 06:30 |
|
idle 01 Feb 2011, 10:59
this is v4:
- new hex macro - rounding corrected, staying experimental - english language only, i'm sorry, let me know and i'll write russian one - macro supports check-code creation main file: Code: ;show_hex <13,10,'$'>, 00, 00, ';',\ ; <13,10,'$'>, 01, 01, ';',\ ; <13,10,'$'>, 02, 02, ';',\ ; <13,10,'$'>, 03, 03, ';',\ ; <13,10,'$'>, 04, 04, ';',\ ; <13,10,'$'>, 05, 05, ';',\ ; <13,10,'$'>, 06, 06, ';',\ ; <13,10,'$'>, 07, 07, ';',\ ; <13,10,'$'>, 08, 08, ';',\ ; <13,10,'$'>, 09, 09, ';',\ ; <13,10,'$'>, 10, 10, ';',\ ; <13,10,'$'>, 11, 11, ';',\ ; <13,10,'$'>, 12, 12, ';',\ ; <13,10,'$'>, 13, 13, ';',\ ; <13,10,'$'>, 14, 14, ';',\ ; <13,10,'$'>, 15, 15, ';',\ ; <13,10,'$'>, 16, 16, ';',\ ; <13,10,'$'>, 17, 17, ';' ; ;repeat 18 ; show_hex <13,10,'$'>, %-1, ';' ;end repeat macro show_hex [intro, val, count, outro]{ common local c, v, d forward display intro c = count if c > 0 & c < 17 v = val while c > 0 c = c - 1 d = v shr (c * 4) and 1111b display d + '0' + d/10*7 if c <> 0 & c mod 4 = 0 display '''' end if end while end if display outro } ;show_frac <13,10,'2^-1 : '>, $8000'0000'0000'0000, ';',\ ; <13,10,'2^-2 : '>, $4000'0000'0000'0000, ';',\ ; <13,10,'2^-1 + 2^-2: '>, $c000'0000'0000'0000, ';' ; ;repeat 64 ; show_frac <13,10>, 1 shl (%-1), '' ;end repeat macro show_frac [intro, val, outro]{ common local a, b forward display intro, '0.' a = (val) and $ffff'ffff b = (val) shr 32 repeat 18 a = a * 10 b = b * 10 + a shr 32 display b shr 32 + '0' a = a and $ffff'ffff b = b and $ffff'ffff if % = 18 display outro else if % mod 3 = 0 display '''' end if end repeat } ;repeat 17 ; display 13,10 ; rcp32 %-1 ;end repeat ; ;repeat 17 ; display 13,10 ; rcp32 %-1, :) ;end repeat macro rcp32 val, check{ local dvs dvs = (val) and $ffff'ffff repeat 1 if dvs < 2 display 13, 10, ':) can you not divide by ', dvs + '0' break end if local dvd, quo, cnt, cnt? dvd = 1 quo = 0 cnt = 0 cnt? = 1 repeat 64 dvd = dvd shl 1 quo = quo shl 1 if dvd < dvs if cnt? = 1 cnt = cnt + 1 end if else cnt? = 0 dvd = dvd - dvs quo = quo + 1 end if end repeat show_hex <13, 10, '; divisor[$1f..$00] = $'> , dvs, 8, '',\ <13, 10, '; 1/divisor[$1f..$00] = $0.'>, quo, 16, '' show_frac '(', quo, ')' repeat 31 if dvs = 1 shl % show_hex <13, 10, 'code: shr eax,$'>, %, 2, ' ; divisor is this power of two' dvs = 0 break end if end repeat if dvs = 0 break end if quo = quo shr (32-cnt-1) if quo and 1 = 1 quo = quo + 10b else quo = quo or 10b end if quo = quo shr 1 show_hex <13, 10, 'code: mov edx,$'>, quo, 8, ' ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$', '', cnt, 2, '), and rounded',\ <13, 10, ' mul edx ; id est div :)'>, , 0, '',\ <13, 10, ' shr edx,$'>, cnt, 2, ' ; compensate quotient' if ~ check eq show_hex <13,10,'; use this code to check rcp32 over',\ 13,10,' call check',\ 13,10,' jne mail_edemko@rambler.ru_about_rounding_error',\ 13,10,' invoke MessageBoxA,0,''rcp32 returned ok'',0,0',\ 13,10,' invoke ExitProcess,0',\ 13,10,'mail_edemko@rambler.ru_about_rounding_error:',\ 13,10,' hlt',\ 13,10,'check: mov esi,$'>,dvs,8,<\ 13,10,' or ecx,-1',\ 13,10,' .loop:xor edx,edx',\ 13,10,' mov eax,ecx',\ 13,10,' div esi',\ 13,10,' mov ebx,eax',\ 13,10,' mov eax,$'>,'',quo,8,<\ 13,10,' mul ecx',\ 13,10,' shr edx,$'>,'',cnt,2,<\ 13,10,' cmp edx,ebx',\ 13,10,' loope .loop',\ 13,10,' ret'> end if end repeat} this... Code: repeat 17 display 13,10 rcp32 %-1 end repeat ...creates this: Code: :) can you not divide by 0 :) can you not divide by 1 ; divisor[$1f..$00] = $0000'0002 ; 1/divisor[$1f..$00] = $0.8000'0000'0000'0000(0.500'000'000'000'000'000) code: shr eax,$01 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0003 ; 1/divisor[$1f..$00] = $0.5555'5555'5555'5555(0.333'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$01), and rounded mul edx ; id est div :) shr edx,$01 ; compensate quotient ; divisor[$1f..$00] = $0000'0004 ; 1/divisor[$1f..$00] = $0.4000'0000'0000'0000(0.250'000'000'000'000'000) code: shr eax,$02 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0005 ; 1/divisor[$1f..$00] = $0.3333'3333'3333'3333(0.199'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0006 ; 1/divisor[$1f..$00] = $0.2AAA'AAAA'AAAA'AAAA(0.166'666'666'666'666'666) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0007 ; 1/divisor[$1f..$00] = $0.2492'4924'9249'2492(0.142'857'142'857'142'857) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0008 ; 1/divisor[$1f..$00] = $0.2000'0000'0000'0000(0.125'000'000'000'000'000) code: shr eax,$03 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0009 ; 1/divisor[$1f..$00] = $0.1C71'C71C'71C7'1C71(0.111'111'111'111'111'111) code: mov edx,$E38E'38E4 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000A ; 1/divisor[$1f..$00] = $0.1999'9999'9999'9999(0.099'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000B ; 1/divisor[$1f..$00] = $0.1745'D174'5D17'45D1(0.090'909'090'909'090'909) code: mov edx,$BA2E'8BA3 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000C ; 1/divisor[$1f..$00] = $0.1555'5555'5555'5555(0.083'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000D ; 1/divisor[$1f..$00] = $0.13B1'3B13'B13B'13B1(0.076'923'076'923'076'923) code: mov edx,$9D89'D89E ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000E ; 1/divisor[$1f..$00] = $0.1249'2492'4924'9249(0.071'428'571'428'571'428) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000F ; 1/divisor[$1f..$00] = $0.1111'1111'1111'1111(0.066'666'666'666'666'666) code: mov edx,$8888'8889 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'0010 ; 1/divisor[$1f..$00] = $0.1000'0000'0000'0000(0.062'500'000'000'000'000) code: shr eax,$04 ; divisor is this power of two this... Code: repeat 17 display 13,10 rcp32 %-1, :) end repeat ...creates this: Code: :) can you not divide by 0 :) can you not divide by 1 ; divisor[$1f..$00] = $0000'0002 ; 1/divisor[$1f..$00] = $0.8000'0000'0000'0000(0.500'000'000'000'000'000) code: shr eax,$01 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0003 ; 1/divisor[$1f..$00] = $0.5555'5555'5555'5555(0.333'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$01), and rounded mul edx ; id est div :) shr edx,$01 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0003 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$01 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0004 ; 1/divisor[$1f..$00] = $0.4000'0000'0000'0000(0.250'000'000'000'000'000) code: shr eax,$02 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0005 ; 1/divisor[$1f..$00] = $0.3333'3333'3333'3333(0.199'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0005 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$CCCC'CCCD mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0006 ; 1/divisor[$1f..$00] = $0.2AAA'AAAA'AAAA'AAAA(0.166'666'666'666'666'666) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0006 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0007 ; 1/divisor[$1f..$00] = $0.2492'4924'9249'2492(0.142'857'142'857'142'857) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0007 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9249'2493 mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0008 ; 1/divisor[$1f..$00] = $0.2000'0000'0000'0000(0.125'000'000'000'000'000) code: shr eax,$03 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0009 ; 1/divisor[$1f..$00] = $0.1C71'C71C'71C7'1C71(0.111'111'111'111'111'111) code: mov edx,$E38E'38E4 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0009 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$E38E'38E4 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000A ; 1/divisor[$1f..$00] = $0.1999'9999'9999'9999(0.099'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000A or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$CCCC'CCCD mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000B ; 1/divisor[$1f..$00] = $0.1745'D174'5D17'45D1(0.090'909'090'909'090'909) code: mov edx,$BA2E'8BA3 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000B or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$BA2E'8BA3 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000C ; 1/divisor[$1f..$00] = $0.1555'5555'5555'5555(0.083'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000C or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000D ; 1/divisor[$1f..$00] = $0.13B1'3B13'B13B'13B1(0.076'923'076'923'076'923) code: mov edx,$9D89'D89E ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000D or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9D89'D89E mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000E ; 1/divisor[$1f..$00] = $0.1249'2492'4924'9249(0.071'428'571'428'571'428) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000E or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9249'2493 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000F ; 1/divisor[$1f..$00] = $0.1111'1111'1111'1111(0.066'666'666'666'666'666) code: mov edx,$8888'8889 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000F or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$8888'8889 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0010 ; 1/divisor[$1f..$00] = $0.1000'0000'0000'0000(0.062'500'000'000'000'000) code: shr eax,$04 ; divisor is this power of two |
|||
01 Feb 2011, 10:59 |
|
idle 01 Oct 2011, 09:08
Code: 2011_??_?? english ~~~~~~~ This file tells how to divide 1 by integer. 1/0 & 1/1 are easy. First we should understand 1/123(e.g.) in decimal to use the principle in binary then. Imagine amount of liquid(e.g. juice). Imagine a vessel of 123 capacity(e.g. a glass). Our task is to fill the vessel with liquid as many times as possible until liquid ends. In other words, you drink juice *glass after a glass* until the juice is drunk. In other words, *each glass* glass count increases, juice decreases. In other words, *each division* quotient increases, dividend decreases. 1 is a unit, consisting of smaller ones: mili- micro- nano- etc-. This is scaling, and we are just storing quotient of mili- micro- nano- etc- size. Ok, let us drink that juice quotient ------------------- 0'001/123 _ <- ones 0'010/123 0._ <- tenths 0'100/123 0.0_ <- hundredths ------------------- 1'000/123 0.00_ <- see, we are dividing mili-ones -0'123 0.001 =0'877 -0'123 0.002 =0'754 -0'123 0.003 =0'631 -0'123 0.004 =0'508 -0'123 0.005 =0'385 -0'123 0.006 =0'262 -0'123 0.007 =0'139 -0'123 0.008 =0'016 ------------------- 0'160/123 0.008_ <- hundredths -0'123 0.0081 =0'037 ------------------- 0'370/123 0.0081_ <- hundredths -0'123 0.00811 =0'247 -0'123 0.00812 =0'124 -0'123 0.00813 =0'001 ------------------- ... _ ------------------- Binary 1/123. It is obvious to get 0..9 in decimal quotient. Hence binary quotient consists of 0..1 only(we either drink the juice or not . Binary juice drunk quotient ----------------- 001/123 _b 002/123 0._b 004/123 0.0_b 008/123 0.00_b 016/123 0.000_b 032/123 0.0000_b 064/123 0.00000_b ----------------- 128/123 0.000000_b -123 0.0000001b =005 ----------------- 010/123 0.0000001_b 020/123 0.00000010_b 040/123 0.000000100_b 080/123 0.0000001000_b ----------------- 160/123 0.00000010000_b -123 0.000000100001b =037 ----------------- 074/123 0.000000100001_b ----------------- 148/123 0.0000001000010_b -123 0.00000010000101b =025 ----------------- ... _b ----------------- 0.00000010000101b = 2^-07 + 2^-12 + 2^-14 = 1.0000101b * 2^-07 = 10000101.b * (2^-07 * 2^-07 = 2^-14) = 133 * 2^-14 = 133 shr 14 How many leading zeros may binary quotient contain? (BSR dividend)[+1] the answer is. Really, to divide by $00ff, 1 grows 8 times into $00100 $ffff, 1 grows 16 times into $10000 $1234, 1 grows 13 times into $02000 ...and only then division(subtraction) starts. [+1] is not required if initial divisor is the power of two: to divide by $0004, 1 grows into $00004 Procedure which returns 1/integer. ... mov eax,10 call dword_rcp ... ;edx = quotient of a .1...xxx form ;ecx = number of consecutive zeros AFTER 0. ;ebx = ? ;eax = old eax = divisor ;flags = ? dword_rcp: divisor equ eax dividend equ ebx leading equ ecx quotient equ edx mov dividend,1 sub leading,leading sub quotient,quotient .drink_juice: inc leading shl dividend,1 ;=dividend+dividend = dividend*2 jc .1 cmp divisor,dividend ja .0 ;divisor denotes units of division .1: sub dividend,divisor ;drink a glass of juice stc .0: rcl quotient,1 ;inserts either 0 or 1 jno .drink_juice ;the most significant bit not 1 sub leading,32 ;number of consecutive zeros AFTER 0. ret restore divisor,dividend,leading,quotient Usage sample. ... mov eax,$CCCC'CCCD ;rounded 0.1 mov edx,65'535 ;arbitrary divisor mul edx ;0.1 * divisor shr edx,3 ;shr edx:eax,32+3 ;edx = 6'553 ... |
|||
01 Oct 2011, 09:08 |
|
idle 03 Oct 2011, 18:35
i misused the two terms
i beg your pardon if it happens again (BSR divisor)[+1] the answer is. mov edx,65'535 ;arbitrary dividend mul edx ;0.1 * dividend english & slavic(ukrainian) |
|||
03 Oct 2011, 18:35 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.