I'm relying on an old implementation that does some calculations and converts float
's to int
.
However, after replicating the calculations some values are off due different rounding results.
It boils down that the binary is using the following code for converting a float
to int
(long
).
lea ecx, [esp+var_8] ; Load Effective Address
sub esp, 10h ; Integer Subtraction
and ecx, 0FFFFFFF8h ; Logical AND
fld st ; Load Real
fistp qword ptr [ecx] ; Store Integer and Pop
fild qword ptr [ecx] ; Load Integer
mov edx, [ecx+4]
mov eax, [ecx]
test eax, eax ; Logical Compare
jz short loc_3 ; Jump if Zero (ZF=1)
loc_1:
fsubp st(1), st ; Subtract Real and Pop
test edx, edx ; Logical Compare
jz short loc_2 ; Jump if Zero (ZF=1)
fstp dword ptr [ecx] ; Store Real and Pop
mov ecx, [ecx]
add esp, 10h ; Add
xor ecx, 80000000h ; Logical Exclusive OR
add ecx, 7FFFFFFFh ; Add
adc eax, 0 ; Add with Carry
retn ; Return Near from Procedure
; ---------------------------------------------------------------------------
loc_2:
fstp dword ptr [ecx] ; Store Real and Pop
mov ecx, [ecx]
add esp, 10h ; Add
add ecx, 7FFFFFFFh ; Add
sbb eax, 0 ; Integer Subtraction with Borrow
retn ; Return Near from Procedure
; ---------------------------------------------------------------------------
loc_3:
test edx, 7FFFFFFFh ; Logical Compare
jnz short loc_1 ; Jump if Not Zero (ZF=0)
fstp dword ptr [ecx] ; Store Real and Pop
fstp dword ptr [ecx] ; Store Real and Pop
add esp, 10h ; Add
retn ; Return Near from Procedure
This behaves differently then simply doing unsigned int var = (unsigned int)floatVal;
.
I believe this is an old ftol
implementation and was done because converting from float
to int
was very slow and the compiler needed to change the FPU rounding mode.
It looks very similar to this one http://www.libsdl.org/release/SDL-1.2.15/src/stdlib/SDL_stdlib.c
Can anyone assist me in converting the function to C? Or tell me how I can create an inline ASM function with float
parameter and return int
using Visual Studio. The one in SDL_sdtlib.c
has no header and I'm not sure how to call it without function args.
This doesn't exactly answer the questions as asked, but I wanted to start by trying a more thorough English translation. It's not perfect, and there are a few lines where I'm still trying to track down the intent. Everyone please speak up with questions and corrections.