Greetings everyone, I know that it's quite an old thread but, I've noticed it just a few days ago and since then I'm trying as hard as I can to implement the casting functions by myself with inline assembly. I think I'm pretty much done with the _ftoui3 (float to unsigned int casting) function, even though I haven't done any exception checking and I don't know how efficient it is, it seems to be working quite nicely. You can judge for yourself:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | __declspec(naked) void _ftoui3() {
__asm {
push ebp
mov ebp, esp
;cvttss2si eax, xmm0 ; This instruction also truncates but stores the value as a signed integer, just like fisttp :(
sub esp, 4
movd [ebp-4], xmm0
fld [ebp-4]
fabs
sub esp, 4
fisttp dword ptr [ebp-8]
mov eax, [ebp-8]
add esp, 8
pop ebp
ret
}
}
|
However, I got stuck on the _dtoui3 (double to unsigned int casting) function. You see, the problem is that although there are indeed instructions that can truncate floating point numbers successfully, they all share a common unfortunate drawback: They all store the truncated value as a signed integer, which will lead to some data loss when a value stored in a double exceeds the limit of a signed integer. I've scanned the whole Internet trying to find different instructions or different methods to tackle this problem but to no avail.
If anyone of you could share your wisdom with me and shed some light on this minor topic, I would appreciate it very much. I'm certain that there is a way since the CRT managed to implement it somehow, but the disassembly of this function looks very intimidating so I can't figure out anything out of it.