I only succeded printing a 64bit double using the %f flag, how can I format a 32bit float with sprintf?
Some other flag or trick?

I checked the documentation for the flags, but I still don't get it.

this is what I got so far to print double, can I get it to print the num32 without converting to 64bit double?



.data
szDll db "MSVCRT.dll",0
szSprintf db "sprintf",0
szFormat db "%f",0
num64 dq 3.141593
num32 dd 1.123

.data?
hSprintf dd ?
buf db 128 dup (?)

.code
START:
invoke LoadLibrary, ADDR szDll
invoke GetProcAddress, eax, ADDR szSprintf
mov hSprintf, eax
push dword ptr num64+4
push dword ptr num64
push offset szFormat
push offset buf
call hSprintf
add esp, 16

invoke MessageBox, 0, ADDR buf, ADDR szSprintf, MB_OK
_quit:
invoke ExitProcess, 0
END START
Posted on 2003-06-28 09:01:59 by david
There isn't a 32-bit float specifier. In a function with variable number of args, all floats in the variable portion are converted (in C or C++) to doubles.
Posted on 2003-06-28 15:22:22 by tenkey
Ok, I see.
thanks. :)
Posted on 2003-06-29 05:55:56 by david
Not only this, but his code is wrong to boot:
.data
szDll db "MSVCRT.dll",0
szSprintf db "sprintf",0
szFormat db "%f",0
num64 dq 3.141593
num32 dd 1.123


.data?
hSprintf dd ?
buf db 128 dup (?)

.code
START:
invoke LoadLibrary, ADDR szDll
invoke GetProcAddress, eax, ADDR szSprintf
mov hSprintf, eax
push dword ptr num64+4
push dword ptr num64
push offset szFormat
push offset buf
call hSprintf
add esp, 16

invoke MessageBox, 0, ADDR buf, ADDR szSprintf, MB_OK
_quit:
invoke ExitProcess, 0
END START


He is defining an 8 byte QWORD at "num64" followed by a 4 byte DWORD (which im unsure if MASM will treat as a REAL4 if you give it a decmalled number). His code indicates only the 4th byte offset into an 8 byte data value, so the value you will see is definitely not what your expecting. As well the string itself for the format has only one %f indicator, yet he is pushing two into the stack.

I would change the DD to REAL4, and add another %f into the format string. As well there may be some issue on some machines having your number data after the strings which would cause the data alignment to be off powers of 4 bytes. To take care of this simply add a "ALIGN 4" before your number data the pointers are aligned on 4 byte boundries.

:alright:
:NaN:
Posted on 2003-07-02 17:20:51 by NaN
Nothing wrong.
num32 isn't used, I'm only printing num64.
That's the correct way to push a 64bit double on the stack to sprintf.
Posted on 2003-07-02 17:25:46 by david
You wanted to print a 32bit float? That was the question as i understood it.

Your code has "offest of the 8 byte QWORD plus 4 = offset of 32bit float" Which is wrong. All offest/pointers are 32 bits, but the data they point to may not be. Its should be "offset of the 8 byte QWORD plus 8 = offset of the 32bit float".

However, additionally to this, Tenkey pointed out that C+ functions expect all floats to be converted to doubles to begin with.

:NaN:
Posted on 2003-07-02 17:28:38 by NaN
I see, you just misunderstood my post Nan.
the code prints the 64bit double which is called num64, this code was what I showed, and I wanted to be able to print the num32 one too.

:)

( close thread )
Posted on 2003-07-02 18:15:03 by david