flat assembler
Message board for the users of flat assembler.

Index > Windows > Convert Floating Point Number To String

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
... so i think it's better to convert half or single to double and then ... .
then how to convert dd float to dq float? i heard something about SSE2 instructions & ..., but i never used them before...
http://docs.oracle.com/cd/E19963-01/html/821-1608/epmpv.html
Post 18 Sep 2012, 09:27
View user's profile Send private message Yahoo Messenger Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
Code:
fld dword[numsingle]
fstp qword[numdouble]    
Post 18 Sep 2012, 19:50
View user's profile Send private message Yahoo Messenger Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
i use this code to load Pi number to a variable:
Code:
fldpi
fstp qword[figure2]    

figure2 is defined by dq. but why when i show figure2, i see 3.142?
Post 18 Sep 2012, 20:41
View user's profile Send private message Yahoo Messenger Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1413
Location: Toronto, Canada
AsmGuru62
It is rounded from 3.1415926 .
Post 18 Sep 2012, 21:11
View user's profile Send private message Send e-mail Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
but this is terrible! how to avoid rounding?... i want more accuracy...
Post 18 Sep 2012, 22:07
View user's profile Send private message Yahoo Messenger Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
Masood.Sandking wrote:
but this is terrible! how to avoid rounding?... i want more accuracy...

this should be enough for a while Smile
http://www.numberworld.org/y-cruncher/
Cheers,

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 18 Sep 2012, 22:23
View user's profile Send private message Visit poster's website Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
thanks, that was incredible!!!
but i want to understand why a double precision number has this low accuracy?! or maybe ftoa procedure has a problem?!
Post 18 Sep 2012, 23:14
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17467
Location: In your JS exploiting you and your system
revolution
Double precision numbers are ~15 decimal digits of accuracy.
Post 19 Sep 2012, 00:41
View user's profile Send private message Visit poster's website Reply with quote
Masood.Sandking



Joined: 12 Jan 2012
Posts: 65
Location: Iran
Masood.Sandking
then why this program outputs 3.142 ? :
Code:
 format pe gui 4.0
entry start 

include '..\include\win32ax.inc' 

BUFF_SIZE       = 256 

section '.rdata' data readable writeable 

  figure1       dd 0.003
  figure2       dq -0.003      ;<< QWORD
  figure3       dd 1234.567 
  figure4       dd -1234.567 
  figure5       dd 123456.789 
  figure6       dd -123456.789

  zero          dd 0.0 
  z1            dd 0.01 
  z3            dd 0.03 
  d1            dd 0.1 
  one           dd 1.0 
  ten           dd 10.0 
  mten          dd -10.0 
  nine          dd 9999.9 

  szMinus       db "-",0 
  szNullDot     db "0.",0 
  szNull        db "0",0 
  szDot         db ".",0 
  szExp         db "E",0 

  digits        db "0123456789ABCDEF",0 

section '.data' readable writeable 

  szBuffer      rb BUFF_SIZE 

section '.text' code readable writable executable 

  ; ------------------------------------------------- 
  ; 
  ; entry-point 
  ; 
  ; ------------------------------------------------- 

  start: 

        ;;fld dword[figure6]         ; Push float1 value to ST(0)
        ;fadd [figure3]    ; Add float2 to ST(0) 
        ;fsqrt
        ;;fstp qword[figure2]    ; Pop value from ST(0) to float1
        ;cvtss2sd xmm0, [figure1]
        ;movss [figure2],xmm0

        fldpi
        fstp qword[figure2]

        stdcall _ftoa,double [figure2],szBuffer
        invoke  MessageBox,NULL,szBuffer,szBuffer,MB_OK+MB_ICONINFORMATION

        invoke  ExitProcess,NULL

  ; ------------------------------------------------- 
  ; 
  ; convert double or float to ascii with proper 
  ; rounding and formatting 
  ; 
  ; ------------------------------------------------- 

  proc  _ftoa uses ebx esi edi,hx:QWORD,hstr 
  locals 
        hdecm   dd ? 
  endl 

        mov     esi,[hstr] 
        xor     ebx,ebx 
        xor     edi,edi 
        cmp     esi,ebx 
        mov     [hdecm],ebx 
        je      .out 
        fld     [zero] 
        fld     [hx] 
        fucompp 
        fnstsw  ax 
        test    ah,68 
        jp      @F 
        invoke  lstrcpy,esi,szNull 
        jmp     .out 
  @@: 
        fld     [hx] 
        fcomp   [zero] 
        fnstsw  ax 
        test    ah,5 
        jp      @F 
        mov     ebx,1 
        fld     [hx] 
        fchs 
        fstp    [hx] 
  @@: 
        fld     [hx] 
        fcomp   [z1] 
        fld     [hx] 
        fnstsw  ax 
        test    ah,5 
        jp      .a 
        fcomp   [d1] 
        fnstsw  ax 
        test    ah,5 
        jp      .conv 
  @@: 
        fld     [hx] 
        dec     edi 
        fmul    [ten] 
        fstp    [hx] 
        fld     [hx] 
        fcomp   [d1] 
        fnstsw  ax 
        test    ah,5 
        jnp     @B 
        jmp     .conv 
  .a: 
        fcomp   [nine] 
        fnstsw  ax 
        test    ah,65 
        jne     .conv 
        fld     [hx] 
        fcomp   [ten] 
        fnstsw  ax 
        test    ah,1 
        jne     .conv 
  @@: 
        fld     [hx] 
        inc     edi 
        fdiv    [ten] 
        fstp    [hx] 
        fld     [hx] 
        fcomp   [ten] 
        fnstsw  ax 
        test    ah,1 
        je      @B 
  .conv: 
        lea     edx,[hdecm] 
        stdcall _cvt,double [hx],3,edx,esi 
        mov     eax,[hdecm] 
        stdcall _formatstring,esi,eax,ebx,edi 
  .out: 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; format ascii figure according to decimal place 
  ; and exponent 
  ; 
  ; ------------------------------------------------- 

  proc  _formatstring uses ebx esi edi,hstr,hdec,hsign,hexp 
  locals 
        buf1    rb 64 
        buf2    rb 64 
  endl 

        xor     eax,eax 
        mov     [buf1],al 
        mov     [buf2],al 
        mov     eax,[hsign] 
        test    eax,eax 
        je      @F 
        lea     eax,[buf1] 
        invoke  lstrcat,eax,szMinus 

  @@: 
        mov     esi,[hdec] 
        test    esi,esi 
        jg      .b 
        lea     ecx,[buf1] 
        invoke  lstrcat,ecx,szNullDot 
        test    esi,esi 
        jge     .a 
        neg     esi 
  @@: 
        lea     edx,[buf1] 
        invoke  lstrcat,edx,szNull 
        dec     esi 
        jne     @B 
  .a: 
        mov     ebx,[hstr] 
        lea     eax,[buf1] 
        invoke  lstrcat,eax,ebx 
        jmp     .d 
  .b: 
        mov     ebx,[hstr] 
        stdcall _strlen_fog,ebx 
        lea     ecx,[buf1] 
        mov     edi,eax 
        stdcall _strncat,ecx,ebx,esi 
        cmp     edi,esi 
        je      .d 
        lea     edx,[buf1] 
        invoke  lstrcat,edx,szDot 
        lea     eax,[ebx+esi] 
        lea     ecx,[buf1] 
        invoke  lstrcat,ecx,eax 
  .d: 
        lea     edx,[buf1] 
        stdcall _strlen_fog,edx 
        dec     eax 
        je      .c 
  @@: 
        cmp     byte [buf1+eax],'0' 
        jne     .c 
        dec     eax 
        mov     byte [buf1+eax+1],0 
        jne     @B 

  .c: 
        mov     cl,byte [buf1+eax] 
        cmp     cl,'.' 
        lea     eax,[buf1+eax] 
        jne     @F 
        mov     byte [eax],0 
  @@: 
        mov     eax,[hexp] 
        test    eax,eax 
        je      @F 
        lea     ecx,[buf2] 
        stdcall _itoa,eax,ecx 
        lea     edx,[buf1] 
        invoke  lstrcat,edx,szExp 
        lea     eax,[buf2] 
        lea     ecx,[buf1] 
        invoke  lstrcat,ecx,eax 
  @@: 
        lea     edx,[buf1] 
        invoke  lstrcpy,ebx,edx 
  .out: 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; convert double/float to a string with proper 
  ; rounding 
  ; 
  ; ------------------------------------------------- 

  proc  _cvt uses ebx esi edi, harg:QWORD,hdigits,hdecpt,hbuf 
  locals 
        r2      dd ? 
        fi      dq ? 
        fj      dq ? 
        tmp     dq ? 
  endl 

        mov     eax,[hdigits] 
        xor     esi,esi 
        cmp     eax,esi 
        jge     @F 
        mov     [hdigits],esi 
        jmp     .a 
  @@: 
        cmp     eax,BUFF_SIZE-1 
        jl      .a 
        mov     [hdigits],BUFF_SIZE-2 
  .a: 
        mov     ebx,[hbuf] 
        mov     [r2],esi 
        mov     edi,ebx 
        fld     [harg] 
        fcomp   [zero] 
        fnstsw  ax 
        test    ah,5 
        jp      @F 
        fld     [harg] 
        fchs 
        fstp    [harg] 
  @@: 
        lea     eax,[fi] 
        stdcall _modf,double [harg],eax 
        fstp    [harg] 
        fld     [zero] 
        fld     [fi] 
        fucompp 
        fnstsw  ax 
        test    ah,68 
        jnp     .int_is_zero 
        lea     esi,[ebx+BUFF_SIZE] 
  @@: 
        fld     [fi] 
        fdiv    [ten] 
        fstp    [tmp] 
        lea     ecx,[fi] 
        stdcall _modf,double [tmp],ecx 
        fadd    [z3] 
        fmul    [mten] 
        fistp   [tmp] 
        dec     esi 
        mov     dl,byte [tmp] 
        mov     al,'0' 
        sub     al,dl 
        mov     [esi],al 
        mov     eax,[r2] 
        inc     eax 
        mov     [r2],eax 
        fld     [zero] 
        fld     [fi] 
        fucompp 
        fnstsw  ax 
        test    ah,68 
        jp      @b 
        lea     eax,[ebx+BUFF_SIZE] 
        cmp     esi,eax 
        jae     .b 
  @@: 
        mov     cl,[esi] 
        mov     [edi],cl 
        inc     edi 
        inc     esi 
        cmp     esi,eax 
        jb      @B 
  .b: 
        mov     esi,[r2] 
  .j: 
        mov     edx,[hdigits] 
        mov     eax,[r2] 
        mov     ecx,[hdecpt] 
        add     esi,edx 
        add     esi,ebx 
        cmp     esi,ebx 
        mov     [ecx],eax 
        jae     .h 
        mov     byte [ebx],0 
        jmp     .out 

  .int_is_zero: 
        fld     [harg] 
        fcomp   [zero] 
        fnstsw  ax 
        test    ah,65 
        jnz     .j 
        fld     [harg] 
        fmul    [ten] 
        fstp    [fj] 
        fld     [fj] 
        fcomp   [one] 
        fnstsw  ax 
        test    ah,5 
        jp      .j 
  @@: 
        dec     esi 
        fld     [fj] 
        fstp    [harg] 
        fld     [fj] 
        fmul    [ten] 
        fstp    [fj] 
        fld     [fj] 
        fcomp   [one] 
        fnstsw  ax 
        test    ah,5 
        jnp     @B 
        mov     [r2],esi 
        jmp     .j 
  .h: 
        cmp     edi,esi 
        ja      .c 
  @@: 
        lea     eax,[ebx+BUFF_SIZE] 
        cmp     edi,eax 
        jae     .c 
        lea     ecx,[fj] 
        fld     [harg] 
        fmul    [ten] 
        fstp    [harg] 
        stdcall _modf,double [harg],ecx 
        mov     ecx,[hdecpt] 
        fstp    [harg] 
        fld     [fj] 
        fistp   [tmp] 
        mov     dl,byte [tmp] 
        add     dl,'0' 
        mov     [edi],dl 
        inc     edi 
        cmp     edi,esi 
        jbe     @B 
  .c: 
        lea     eax,[ebx+BUFF_SIZE] 
        cmp     esi,eax 
        jb      @F 
        mov     byte [ebx+255],0 
        jmp     .out 

  @@: 
        mov     dl,[esi] 
        add     dl,5 
        mov     eax,esi 
        mov     [esi],dl 
        cmp     dl,'9' 
        jle     .d 
  .g: 
        mov     byte [esi],'0' 
        cmp     esi,ebx 
        jbe     .e 
        mov     dl,[esi-1] 
        dec     esi 
        inc     dl 
        mov     [esi],dl 
        jmp     .f 
  .e: 
        mov     byte [esi],'1' 
        mov     edi,[ecx] 
        inc     edi 
        cmp     eax,ebx 
        mov     [ecx],edi 
        jbe     @F 
        mov     byte [eax],'0' 
  @@: 
        inc     eax 
  .f: 
        cmp     byte [esi],'9' 
        jg      .g 
  .d: 
        mov     byte [eax],0 
  .out: 
        mov     eax,ebx 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; return fractional part in st0 and integer 
  ; part in y (pointer to a qword) 
  ; 
  ; ------------------------------------------------- 

  proc  _modf uses edi, x:QWORD,y 
  locals 
        cw1     dw ? 
        cw2     dw ? 
  endl 
        mov     edi,[y] 
        fnstcw  [cw1] 
        fwait 
        mov     ax,[cw1] 
        or      ax,110000111111b 
        mov     [cw2],ax 
        fldcw   [cw2] 
        fwait 
        fld     [x] 
        frndint 
        fstp    qword [edi] 
        fwait 
        fld     [x] 
        fsub    qword [edi] 
        fldcw   [cw1] 
        fwait 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; integer to ascii conversion (reverend) 
  ; 
  ; ------------------------------------------------- 

  proc  _itoa uses ebx esi edi, number,result_buffer 
  locals 
        temp_buffer                   rb 32+1 
  endl 

        push    10 
        pop     esi 
        lea     edi,[temp_buffer+32] 
        mov     ebx,digits 
        cmp     esi,16 
        ja      .error 
        std 
        xor     al,al 
        stosb 
        mov     eax,[number] 
        test    eax,80000000h 
        jz      @F 
        neg     eax 
  @@: 
        xor     edx,edx 
        idiv    esi 
        xchg    eax,edx 
        xlatb 
        stosb 
        xchg    eax,edx 
        test    eax,eax 
        jnz     @B 
        lea     esi,[edi+1] 
        mov     edi,[result_buffer] 
        cld 
        test    [number],80000000h 
        jz      @F 
        mov     al,'-' 
        stosb 
  @@: 
        lodsb 
        stosb 
        test    al,al 
        jnz     @B 
        sub     edi,[result_buffer] 
        lea     eax,[edi-1] 
        stc 
        jmp     .theend 
  .error: 
        clc 
  .theend: 
        cld 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; return length of hstr string in eax (Agner Fog) 
  ; pretty fast algorithm 
  ; 
  ; ------------------------------------------------- 

  proc  _strncat uses ebx esi edi, hfront,hback,hcount 
        mov     esi,[hfront] 
        stdcall _strlen_fog,esi 
        mov     edx,eax 
        add     edx,esi 
        mov     edi,[hcount] 
        test    edi,edi 
        jz      .out_null 
        mov     esi,[hback] 
  @@: 
        mov     cl,[esi] 
        mov     [edx],cl 
        dec     edi 
        inc     edx 
        inc     esi 
        test    cl,cl 
        jz      .out 
        test    edi,edi 
        jnz     @B 
  .out_null: 
        xor     al,al 
        mov     byte [edx],al 
  .out: 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; return length of hstr string in eax (Agner Fog) 
  ; pretty fast algorithm 
  ; 
  ; ------------------------------------------------- 

  proc  _strlen_fog uses ebx esi edi, hstr 
        mov     eax,[hstr] 
        lea     edx,[eax+3] 
  @@: 
        mov     ebx,[eax] 
        add     eax,4 
        lea     ecx,[ebx-01010101h] 
        not     ebx 
        and     ecx,ebx 
        and     ecx,80808080h 
        jz      @B 
        test    ecx,00008080h 
        jnz     @F 
        shr     ecx,16 
        add     eax,2 
  @@: 
        shl     cl,1 
        sbb     eax,edx 
        ret 
  endp 

  ; ------------------------------------------------- 
  ; 
  ; fast memory copying algorithm (tuned asmpack ver) 
  ; qword -> dword -> byte 
  ; 
  ; ------------------------------------------------- 

  proc  _memcpy_fast uses esi edi, hdst,hsrc,hsize 
        mov     eax,[hsize] 
        mov     edi,[hdst] 
        mov     esi,[hsrc] 
        mov     ecx,eax 
        shr     ecx,3 
        jz      .next1 
  @@: 
        movq    mm0,qword [esi] 
        movq    qword [edi],mm0 
        add     esi,8 
        add     edi,8 
        dec     ecx 
        jnz     @B 
  .next1: 
        mov     ecx,eax 
        and     ecx,7 
        shr     ecx,2 
        jz      .next2 
  @@: 
        mov     edx,[esi] 
        mov     [edi],edx 
        add     esi,4 
        add     edi,4 
        dec     ecx 
        jnz     @B 
  .next2: 
        and     eax,3 
        jz      .out 
  @@: 
        mov     dl,byte [esi] 
        mov     byte [edi],dl 
        inc     esi 
        inc     edi 
        dec     eax 
        jnz     @B 
  .out: 
        sub     edi,[hsize] 
        mov     eax,edi 
        ret 
  endp 

section '.idata' import data readable writeable 

  library       kernel32,'kernel32.dll',\ 
                user32,'user32.dll',\ 
                gdi32,'gdi32.dll',\ 
                comdlg32,'comdlg32.dll',\ 
                advapi32,'advapi32.dll' 

  include       '..\include\api\kernel32.inc' 
  include       '..\include\api\user32.inc' 
  include       '..\include\api\gdi32.inc' 
  include       '..\include\api\comdlg32.inc' 
  include       '..\include\api\advapi32.inc' 

; eof    


guys sorry for asking too many questions! i'm beginner.
Post 19 Sep 2012, 01:37
View user's profile Send private message Yahoo Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17467
Location: In your JS exploiting you and your system
revolution
Masood.Sandking wrote:
then why this program outputs 3.142 ?
Because you only asked for 3 digits:
Quote:
stdcall _cvt,double [hx],3,edx,esi
Post 19 Sep 2012, 01:43
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.