flat assembler
Message board for the users of flat assembler.
Index
> Windows > Convert Floating Point Number To String Goto page Previous 1, 2 |
Author |
|
Masood.Sandking 18 Sep 2012, 09:27
... 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 |
|||
18 Sep 2012, 09:27 |
|
Masood.Sandking 18 Sep 2012, 19:50
Code: fld dword[numsingle] fstp qword[numdouble] |
|||
18 Sep 2012, 19:50 |
|
AsmGuru62 18 Sep 2012, 21:11
It is rounded from 3.1415926 .
|
|||
18 Sep 2012, 21:11 |
|
Masood.Sandking 18 Sep 2012, 22:07
but this is terrible! how to avoid rounding?... i want more accuracy...
|
|||
18 Sep 2012, 22:07 |
|
hopcode 18 Sep 2012, 22:23
Masood.Sandking wrote: but this is terrible! how to avoid rounding?... i want more accuracy... this should be enough for a while http://www.numberworld.org/y-cruncher/ Cheers, _________________ ⠓⠕⠏⠉⠕⠙⠑ |
|||
18 Sep 2012, 22:23 |
|
Masood.Sandking 18 Sep 2012, 23:14
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?! |
|||
18 Sep 2012, 23:14 |
|
revolution 19 Sep 2012, 00:41
Double precision numbers are ~15 decimal digits of accuracy.
|
|||
19 Sep 2012, 00:41 |
|
Masood.Sandking 19 Sep 2012, 01:37
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. |
|||
19 Sep 2012, 01:37 |
|
revolution 19 Sep 2012, 01:43
Masood.Sandking wrote: then why this program outputs 3.142 ? Quote: stdcall _cvt,double [hx],3,edx,esi |
|||
19 Sep 2012, 01:43 |
|
indinaman 28 Nov 2020, 02:26
format PE console 4.0
entry main include 'win32a.inc' section '.data' data readable writeable num1 dq 48.6 num2 dq 17.1 result dq ? fmt db " %.9f",13,10,0 fmt2S db " %s",13,10,0 ;szBuff db 32 dup (0) numS rb 15 section '.code' code readable executable main: fld qword [num1] fld qword [num2] fmulp fstp qword [result] invoke printf, fmt, dword[result] ,dword[result+4] fld qword [num1] fld qword [num2] fdivp fstp qword [result] invoke printf, fmt, dword[result] ,dword[result+4] fld qword [num1] fld qword [num2] faddp fstp qword [result] invoke printf, fmt, dword[result] ,dword[result+4] fld qword [num1] fld qword [num2] fsubp fstp qword [result] invoke printf, fmt, dword[result] ,dword[result+4] invoke _gcvt,dword[result],dword[result+4],15,numS invoke printf, fmt2S,numS ;String Number cinvoke getchar invoke ExitProcess, 0 section '.idata' import data readable library kernel32,'kernel32.dll', msvcrt,'msvcrt.dll' import kernel32, ExitProcess,'ExitProcess' import msvcrt,\ getchar,'getchar',\ atof,'atof',\ strtod,'strtod',\ rand,'rand',\ _gcvt,'_gcvt',\ printf,'printf' |
|||
28 Nov 2020, 02:26 |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.