flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > unlimited floats, no mul, no div, small size, etc happy

Author
Thread Post new topic Reply to topic
idle



Joined: 06 Jan 2011
Posts: 440
Location: Ukraine
idle 08 Jun 2011, 22:30
Tomasz, your birthday soon :)
Code:
;enu: get binary representation of decimal fraction
;     decimal fraction stored in binary-coded-decimal format
;     as there are no limits to input, byte -1 should precede it: db -1, 6,2,5,..
;     that example implies you want to get 0.625 in binary
;     it can all be used in unlimited floats representation
;     it can also be used to mul bcd's by powers of two
;     ask your quests to edemko@rambler.ru please
;
;     on init do smth like:
;       decimal_fraction db -1, 6,2,5,0,0,0
;         .:
;       ...
;       mov     edi,decimal_fraction.-1
;       call    frac
;       ...
;
;     on exit:
;       edx:ebp:ebx - normalized fraction
;       ecx         - steps to get real fraction(denormalized)
;       edi         - rank0 position of fraction
;       esi         - byte -1 position +1
;       flags.df    - 1
;       flags       - ?

;rus: TODO
frac:   sub     edx,edx           ;assume empty fraction
        sub     ebp,ebp
        sub     ebx,ebx

        std                       ;skip trailing zeros
        sub     eax,eax
        lea     ecx,[eax-1]
        repe    scasb
        sub     ecx,ecx           ;total number of multiplications we'll do
        cmp     al,-1
        je      .ret              ;fraction = .0

        inc     edi               ;remember decimal rank0 location
.until_normalized:
        mov     esi,edi
        mov     ah,0              ;no carries initially
.load:  lodsb                     ;get current rank digit
        cmp     al,10
        jb      .mul              ;common digit
        inc     ecx
        shr     ah,1
        rcl     ebx,1
        rcl     ebp,1
        rcl     edx,1
        test    edx,edx
        jns     .until_normalized
        sub     ecx,32*3          ;number of preceding zeros we've removed = denormalization steps count
.ret:   ret     0
.mul:   shr     ah,1              ;include carry from previous rank operation
        adc     al,al             ;digit*2 + carry
        cmp     al,10
        jb      .store            ;else we correct result into a bcd(lazy) form
        add     al,256-10
        mov     ah,1
.store: mov     [esi+1],al
        jmp     .load
    



edit: + russian intro here:
http://fasmme.googlecode.com/files/frac.inc
Post 08 Jun 2011, 22:30
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 440
Location: Ukraine
idle 11 Jun 2011, 12:26
hi
small bug was found
link from previous post not available
could not refuse that patch, remove "once" in example not to use it
Post 11 Jun 2011, 12:26
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 440
Location: Ukraine
idle 12 Jun 2011, 02:23
use old links
<frac> did not restore CLD - in case of zero previous code wrote data wrong direction :) - fixed
previous code used fpu, this one does not, bringing even more precise results(~20 decimal points)
i386-compatible
so recognized text becomes a number:
Code:
.d_:                              ;read <frac> intro 1st
        cmp     ah,0
        jz      .d_z              ;the biggest digit is 0
        bt      ecx,30            ;point met?
        jc      .d_edx_defined
        movzx   edx,cl            ;all part is integer
    .d_edx_defined:
        dec     edx               ;power of ten
        push    edx
        call    frac              ;have you read <frac> intro?
        not     ecx
        dec     ecx
        and     cx,$3fff          ;biased power of two, fpu form
        mov     edi,edx           ;so edi:ebp:ebx = fraction
        xchg    esi,[esp]
    .d_mul:
        test    esi,esi           ;flags.cf=0
        jz      .d_nz
        dec     esi
        mov     eax,10
        mul     ebx
        mov     ebx,eax
        xchg    ebp,edx
        mov     eax,10
        mul     edx
        add     ebp,eax
        xchg    edi,edx
        adc     edi,0
        mov     eax,10
        mul     edx
        add     edi,eax
        adc     edx,0
        bsr     eax,edx
        inc     eax               ;>0
        add     ecx,eax           ;increase power of two
        xchg    ecx,eax           ;normalization
        shrd    ebx,ebp,cl
        shrd    ebp,edi,cl
        shrd    edi,edx,cl
        mov     ecx,eax
        jmp     .d_mul
    .d_nz:
        pop     esi
        mov     [esi+1],ebp
        mov     [esi+5],edi
        mov     [esi+9],cx
        lea     edi,[esi+11]
        mov     al,'d'
        pop     esi
        ret     0
    .d_z:
        sub     eax,eax
        stosd
        stosd
        stosw
        mov     al,'d'
        pop     esi
        ret     0
    
Post 12 Jun 2011, 02:23
View user's profile Send private message Reply with quote
idle



Joined: 06 Jan 2011
Posts: 440
Location: Ukraine
idle 30 Jun 2011, 11:54
Code:
        ;cmp     al,10
        ;jb      .store            ;else we correct result into a bcd(lazy) form
        ;add     al,256-10
        ;mov     ah,1              ;= adc ah,ah
        aaa                        ;2011_06_30
    

move to Main if preferred, thank you for attention :)



LAST EDIT HERE: now here:
http://board.flatassembler.net/topic.php?t=12980
Post 30 Jun 2011, 11:54
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.