News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Converting a Real10 to string

Started by RuiLoureiro, April 28, 2013, 05:26:33 AM

Previous topic - Next topic

dedndave

prescott w/htt - xp mce2005 sp3
3,141592653589793238E+0000
3.141592653589793238
*** STOP - Eprst+ConvertReal10KX- PI ***
580 cycles, Eprst, _Real10_PI

340 cycles, ConvertReal10KX, _Real10_PI

571 cycles, Eprst, _Real10_PI

340 cycles, ConvertReal10KX, _Real10_PI


***** Time table *****

Intel(R) Pentium(R) 4 CPU 3.00GHz (SSE3)

340  cycles, ConvertReal10KX -19 digits
340  cycles, ConvertReal10KX -19 digits
571  cycles, Eprst -19 digits
580  cycles, Eprst -19 digits
*** END converting PI - Eprst + ConvertReal10KX- ***

dedndave

EvalReal takes about 3,000 cycles   :lol:

Mikl__

3,141592653589793238E+0000
3.141592653589793238
*** STOP - Eprst+ConvertReal10KX- PI ***
165 cycles, Eprst, _Real10_PI

179 cycles, ConvertReal10KX, _Real10_PI

165 cycles, Eprst, _Real10_PI

177 cycles, ConvertReal10KX, _Real10_PI


***** Time table *****

Intel(R) Pentium(R) CPU G860 @ 3.00GHz (SSE4)

165  cycles, Eprst -19 digits
165  cycles, Eprst -19 digits
177  cycles, ConvertReal10KX -19 digits
179  cycles, ConvertReal10KX -19 digits
*** END converting PI - Eprst + ConvertReal10KX- ***

$MagicLog2_32    equ 1292913987     ; = log(2) * 2^32
    dp_1    equ 17      ; = decimal places minus 1
    dp4     equ dp_1+4
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; Input:
;           esi = 10
;
EXPONENTREAL_10KM MACRO
;to calculate the absolute value of a signed integer without branching
                cdq
                xor      eax,edx
sub eax,edx            ; make number positive
                and dl,2
                add      byte ptr[edi+22],dl;if eax>=0 then "plus" else "minus"
                mov      edx,4294968        ;2^32/1000
                mul      edx                ;extend first digit
                shrd     ecx,edx,8          ;digit 1 in ECX
                mul      esi                ;extend second digit
                shrd     ecx,edx,8          ;digit 2 in ECX
                mul      esi                ;extend third digit
                shrd     ecx,edx,8          ;digit 3 in ECX
                mul      esi                ;extend fourth digit
                shrd     ecx,edx,8          ;digit 4 in ECX
                or       [edi+23],ecx       ;make ASCII string               
ENDM
;---------------------------------------------
$maxexp     equ 90
$maxcounter equ 2*$maxexp+1
;---------------------------------------------
.data
realexp4931    dt 1.0e+4931
        shifttableX    dd shift0X    ; +0
                        dd shift1X    ; +4
                        dd shift2X    ; +8
                        dd shift3X    ;+12
                        dd shift4X    ;+16
;---------------------------------------------
    cntr = -$maxexp
    REPEAT $maxcounter
        IF cntr NE 0
            dt @CatStr(<1.0e>,%-cntr)
        ELSE
PowerTable12  dt 1.0
        ENDIF
            dw 0
        cntr = cntr + 1
    ENDM
;----------------------------------------------------
.code

align 16
Eprst         proc
; locals, buffer and args
pReal10 equ dword ptr [esp+16+buffer]
pStr equ pReal10+4
iExp equ dword ptr [esp-4];0+4=4
aExp equ iExp-4           ;4+4=8
realx equ aExp-4*3         ;8+12=20
temp equ realx-4*3        ;20+12=32
buffer = 20h     
                        ;
                          push    ebx
                          push    esi
                          push    edi
                          sub   esp, buffer
                          mov     ecx, pReal10                                         
                        ; ---------------------------
                        ;        remove sign
                        ;    move real10 to realx
                        ; if iExp=0 we use this realx
                        ; ---------------------------
;to calculate the sign of number without branching

                  mov     edx, dword ptr [ecx+6]
                  add   edx, edx; if CF=1 then negative
                  mov     edi, pStr
  sbb     eax, eax; if CF=0 then EAX = 0 else EAX = -1
                          and   eax, 0Dh
                          mov     aExp, 0
                          or      eax, 2C0020h
                          mov   [edi], eax; if CF=0 then EAX = 2C0020h else EAX = 2C002Dh
                  shr   edx, 17 ; remove sign and if EDX = 0 go to _expzero

                  mov     ebx, [ecx+0]
                  mov     ecx, [ecx+4]

                  mov     [realx+0], ebx
                  mov     [realx+4], ecx
                  mov     [realx+8], edx ; only exponent
                  jz      _expzero ; if exponent = 0       
        _expnotzero:      cmp     edx, 7FFFh
                  je      _isinfinity
                        ;
                          test    ecx, ecx
                          jns     _erro1   ; if integer = 0 and exponent <> 0 then ERROR
                          mov     ecx, pReal10
                          fld   tbyte ptr [ecx]
                          jmp     _begin
                        ; ------------------------
                        ;       exponent = 0
                        ; ------------------------
_expzero:                 or      ebx, ecx
                          jz      _iszero       ; if edx = ebx = ecx = 0 is zero
                          mov     ecx, pReal10
                          fld   tbyte ptr [ecx]
                        ;-------------------------
                        ;    It is Denormal or
                        ;     Pseudo-Denormal
                        ;-------------------------
                          fld     realexp4931     ; st(0)=1.0e+4931
                  mov     aExp,-4931
                  fmul                     ; normalization
                  fld     st               ; get a copy
                  fstp    tbyte ptr realx
                        ;
                  mov     ebx, [realx+0]
                  and   [realx+8],7FFFh; remove sign FABS
                  mov     eax, [realx+4]
                  mov     edx, [realx+8]
                        ;---------------------
                        ;       start
                        ;---------------------
                _begin:   mov     esi, 10                                                   
;-----------------------------------------------------------------
;FILD + FLDLG2 + FMUL + FISTP                                             

  mov     eax, $MagicLog2_32   ; log(2)*2^32
                  sub     edx, 3FFFh           ; =16383
                  imul    edx
                  mov     iExp, edx
  or   edx,edx
                          jz      short _getrealx ;edx = 0 ?
                          cmp   edx, -1
                          je      _new ;integer multipication to 10
                  cmp     edx, $maxexp
                  jg      @F
                  cmp     edx,-$maxexp
                  jge     short _load
;------------------------------------------------
;FSCALE is slow on all processors. Computing integer powers of 2 can be done
;much faster by inserting the desired power in the exponent field of the
;floating-point number.

                 @@:      neg     edx
                  fldl2t   ; log2(10)
                  mov     [temp+8],edx           
                  fild    [temp+8]        ; x
  mov     [temp+0],0
                          fmul                    ; z = x * log2(10)
  mov     [temp+4],3F000000h ; 0.5
                          fld     st
                          fsub    [temp+4]        ; z - 0.5
                          fistp   [temp+8]        ; round(z)
          mov     [temp+4],80000000h
          fisub   [temp+8]        ;z - round(z)
                          f2xm1                   ; 2^(mantissa)-1
          add     [temp+8],3FFFh  ; 2^round(z)
                          fld1
                          fadd                    ; add 1 and pop
                          fld     tbyte ptr temp
                          fmul                    ; 2^((mantissa)*round(z))
                          jmp     short @F        ;_multiply                       
;--------------------------------------------------------       
            _load:   shl     edx, 2                       ; edx = edx*4
                          fld     [PowerTable12+edx+edx*2]    ; edx = edx*12
;--------------------------------------------------------             
                @@:       fmul                    ; X * 10^expscaleS = d.??????             
                  fld      st              ; get a copy
                  fstp     tbyte ptr realx
                  xor      edx, edx
                  mov      ebx, [realx+0]
;----------------------------------------------------------------
        _getrealx:        mov      ecx, [realx+8]
                          mov      eax, [realx+4]
                        ;
                  and      ecx, 7FFFh
                  sub      ecx, 16382      ; 10=> exponent = 16386

                  cmp      ecx, 4
                  ja       shift0X
                  jmp      [shifttableX+ecx*4]
_new:                     mov      eax, ebx;[realx+0]
                          add      eax,1
                          mul      esi
                          mov      ebx, eax
                          mov      ecx, edx
                          mov      eax, [realx+4]
                          mul      esi
                          add      eax, ecx
                          jmp      _aa

           shift4X::      test     eax, 60000000h              ; 6= 0110B
                  jz       short a6

                        ; ------------------------
                        ; correct exponent * 10^-1
                        ; exponent = exponent + 1
                        ; ------------------------
                  fld      [PowerTable12+12]          ; = 0.1
                  fmul
                  add      iExp, 1

                  fld      st                  ; NEW get a copy
                  fstp     tbyte ptr realx

                  mov      eax, [realx+4]
                          mov      ebx, [realx+0]
                  jmp      shift1X

                a6:   shld     edx, eax, 4        ;ecx=1 ebx+4
                  shld     eax, ebx, 4        ;ecx=2 ebx+8
                  shl      ebx, 4             ;ecx=3 ebx+9
                  add      ebx, 12;round       ;ecx=4 ebx+12
                  jmp      shift0X

                        ; -------------------------------
                        ;    fraction bits in EAX:EBX
                        ;    shift: EDX <- EAX <- EBX
                        ; -------------------------------
           shift3X::      shld     edx, eax, 3
                  shld     eax, ebx, 3
                  shl      ebx, 3              ; * 8
                  add      ebx, 10 ;round
                  jmp      shift0X

                        ; -------------------------------
                        ;    fraction bits in EAX:EBX
                        ;    shift: EDX <- EAX <- EBX
                        ; -------------------------------
           shift2X::      shld     edx, eax, 2
                  shld     eax, ebx, 2
                  shl      ebx, 2              ; * 4
                  add      ebx, 8              ;round
                  jmp      shift0X

                        ; -------------------------------
                        ;    fraction bits in EAX:EBX
                        ;    shift: EDX <- EAX <- EBX
                        ; -------------------------------
           shift1X::      shld     edx, eax, 1
                  shld     eax, ebx, 1
                  shl      ebx, 1              ; * 2
                  add      ebx, 4              ;round
;-------------------------------------------------------
                        ; -------------------------------
                        ;  fraction bits in EDX:EAX:EBX
                        ; -------------------------------
           shift0X::      adc      eax, 0          ; add carry to eax and edx
    _aa:          adc      edx, '0'        ; ASCII convert
                        ;
                          mov      dword ptr [edi+21],'00+E';ASCII chars for exponent
  mov      dword ptr [edi+25],'00'
                  mov      [edi+1], dl     ;first char in string
                        ;------------------------------------------------
                        ;                 eax    ebx
                        ;                        10
                        ;                -----------
                        ;                 ecx    ebx
                        ;         edx     eax                       
                        ;    ------------------------
                        ;   edx+carry     eax    ebx
                        ;------------------------------------------------
                    k=3
                        REPEAT dp_1
                            mov     ecx,eax         ; save EAX
                            mov     eax,ebx
                            mul     esi             ; edx:eax=ebx*10
                            mov     ebx,eax
                            mov     eax,ecx         ; restore EAX
                            mov     ecx,edx         ; save EDX
                            mul     esi             ; edx:eax=eax*10
                            add     eax,ecx
                            adc     edx,'0'         ; ASCII convert
                            mov     [edi+k], dl     ; next char in string
                    k=k+1
                        ENDM
                            mov     ecx,eax         ; save EAX
                            mov     eax,ebx
                            mul     esi             ; edx:eax=ebx*10
                            mov     eax,ecx         ; restore EAX
                            mov     ecx,edx         ; save EDX
                            mul     esi             ; edx:eax=eax*10
                            add     eax,ecx
                            adc     edx,'0'         ; ASCII convert
                    mov     eax, iExp
                            mov     [edi+k], dl     ; last char in string
                            add     eax, aExp
                            jz      _exit ;if exponent=0 go to exit

                        EXPONENTREAL_10KM

            _exit:      mov edi,[esp+buffer] ;restore edi
                        mov esi,[esp+buffer+4] ;restore esi
                        mov ebx,[esp+buffer+8] ;restore ebx
                        fstp     st(0)              ;remove realx
                        add esp,buffer+12 ;remove buffer,locals
                        xor      eax, eax               ;sucsess code
                        retn 8 ;go to main program
;-----------------------------------------------------------
    _isinfinity:        test      ecx,ecx
                        jns      short _erro1               ; is NAN
                        cmp      ecx,80000000h
                        jnz      _other
                        or       ebx, ebx
                        jne      short _erro1               ; is NAN
                        mov      dword ptr [edi+1], "IFNI"
                        mov      dword ptr [edi+5], "YTIN"
                        mov      dword ptr [edi+9],0
                        xor      eax, eax
                        mov edi,[esp+buffer];pop      edi
                        mov esi,[esp+buffer+4];pop      esi
                        mov ebx,[esp+buffer+8];pop      ebx
                        add esp,buffer+12
                        ret 8
                        ;--------------------------
                        ; value to be converted = 0
                        ;--------------------------
        _iszero:        mov esi,[esp+buffer+4];pop      esi
                        mov      dword ptr [edi+1],"0.0"
                        mov ebx,[esp+buffer+8];pop      ebx
                        mov edi,[esp+buffer];pop      edi
                        add esp,buffer+12
                        xor      eax, eax
                        ret 8
                        ; --------------------
                        ; is indefinite or NAN
                        ; --------------------
        _erro1:         mov      eax, 1
                        mov      dword ptr [edi+1], "ORRE"
                        mov      dword ptr [edi+5], "R"
                        stc
                        mov edi,[esp+buffer];pop      edi
                        mov esi,[esp+buffer+4];pop      esi
                        mov ebx,[esp+buffer+8];pop      ebx
                        add esp,buffer+12
                        ret 8
        _other:         test    ecx,0BFFFFFFFh
                        jnz     _other1
                        mov      dword ptr [edi+1], "ngiS"
                        mov      dword ptr [edi+5], "nila"
                        mov      dword ptr [edi+9], "aN g"
                        mov      dword ptr [edi+13],"N"
                        xor      eax, eax
                        mov edi,[esp+buffer];pop      edi
                        mov esi,[esp+buffer+4];pop      esi
                        mov ebx,[esp+buffer+8];pop      ebx
                        add esp,buffer+12
                        ret 8
_other1:        cmp      ecx,0C0000000h
                        jnz     _Quit_NaN
                        or       ebx, ebx
                        jne     _Quit_NaN
                        mov      dword ptr [edi+1], "ednI"
                        mov      dword ptr [edi+5], "inif"
                        mov      dword ptr [edi+9], "et"
                        xor      eax, eax
                        mov edi,[esp+buffer];pop      edi
                        mov esi,[esp+buffer+4];pop      esi
                        mov ebx,[esp+buffer+8];pop      ebx
                        add esp,buffer+12
                        ret 8
      _Quit_NaN:        mov      dword ptr [edi+1], "eiuQ"
                        mov      dword ptr [edi+5], "aN t"
                        mov      dword ptr [edi+9], "N"
                        xor      eax, eax
                        mov edi,[esp+buffer];pop      edi
                        mov esi,[esp+buffer+4];pop      esi
                        mov ebx,[esp+buffer+8];pop      ebx
                        add esp,buffer+12
                        ret 8
Eprst         endp

dedndave

3,141592653589793238E+0000
3.141592653589793238
*** STOP - Eprst+ConvertReal10KX- PI ***
361 cycles, Eprst, _Real10_PI

340 cycles, ConvertReal10KX, _Real10_PI

344 cycles, Eprst, _Real10_PI

346 cycles, ConvertReal10KX, _Real10_PI

***** Time table *****

Intel(R) Pentium(R) 4 CPU 3.00GHz (SSE3)

340  cycles, ConvertReal10KX -19 digits
344  cycles, Eprst -19 digits
346  cycles, ConvertReal10KX -19 digits
361  cycles, Eprst -19 digits
*** END converting PI - Eprst + ConvertReal10KX- ***

RuiLoureiro

Hi all
Mikl__, aqui está o trabalho que desenvolveste ( e eu colaborei )
e que tu aqui deixaste.
Very nice !
Thank you  :t