It works fine but not with values as precise as 20.723456 where it just ends up in a loop.
It's stdcall. It can be called like so and supplied to printf
Code: Select all
long long i = ffractionalpart(20.72345)
Code: Select all
FLOAT_TEN dd 10.0
DLLEXPORT ffractionalpart
.value EQU 0 +8
push ebp
mov ebp, esp
sub esp, 16
.outVal EQU 8
.remainder EQU 16
fld QWORD [ebp+.value]
fisttp DWORD [ebp-.outVal] ; outVal = integer part
fld QWORD [ebp+.value]
fisub DWORD [ebp-.outVal] ; outVal -= integer part
fstp DWORD [ebp-.outVal] ; outVal = 0.xxxxx
; Multiply by 10 & mod by 1 until remainder == 0
.loop:
fld1
fld DWORD [ebp-.outVal] ; st0 = outVal, st1 = 1.0
fprem ; st0 = remainder == st0 % st1
fldz ; st1 = remainder, st0 = 0.0
fcomp
fstsw ax
fstp
and ah, 01000111b
cmp ah, 01000000b
je .ok
.next:
fld DWORD [ebp-.outVal]
fmul DWORD [FLOAT_TEN]
fstp DWORD [ebp-.outVal]
jmp .loop
.ok:
fld DWORD [ebp-.outVal]
fabs
fisttp QWORD [ebp-.outVal]
mov edx, DWORD [ebp-.outVal+4]
mov eax, DWORD [ebp-.outVal]
.done:
add esp, 16
pop ebp
add esp, 8+4
jmp DWORD [esp-(8+4)]