I stumbled upon this (reduced for readability) function. It does weird things that I have never encountered before.
// a2 is always 60.0
void some_function(struct_123 *this, float a1, float a2)
{
float v5; // ST10_4
float v6; // ST14_4
this->field_34 = a1;
v5 = a2 / (0.011 * 1000.0); // 60.0 / 11.0
v6 = v5 - (double)(signed int)v5;
this->field_38 = (SLODWORD(v6) >> 31) + (signed int)v5;
}
I know a little bit about IEEE 754 decimals, so i think (SLODWORD(v6) >> 31)
yields v6's sign bit. I suspect this is some kind of inlined floor/ceiling rounding operation, but I am anything but sure about this.
Edit: I stumbled upon the actual non-inlined method. Here it is:
int __cdecl float_sub_466560(float a1)
{
float v1; // ST04_4
v1 = (double)(signed int)a1 - a1;
return (signed int)a1 - (SLODWORD(v1) >> 31);
}
Edit 2: it seems like the first function I gave adds 1 in the last line. That is part of the function, not the floating point operation. I removed it.
Edit 3: as requested, here is the assembly for the second function. I can provide the assembly from the first function, however it is quite big, and I don't really want to extract the right portion of it if it's not necessary.
float_sub_466560 proc near
var_8 = dword ptr -8
var_4 = dword ptr -4
arg_0 = dword ptr 4
sub esp, 8 ; stack frame
fld [esp+8+arg_0] ; Load Real
fist [esp+8+var_8] ; Store Integer
fisubr [esp+8+var_8] ; Subtract Integer Reversed
fstp [esp+8+var_4] ; Store Real and Pop
mov eax, [esp+8+var_4]
mov ecx, [esp+8+var_8]
sar eax, 1Fh ; Shift Arithmetic Right
sub ecx, eax ; Integer Subtraction
mov eax, ecx ; move result to correct return register
add esp, 8 ; stack frame
retn ; Return Near from Procedure
float_sub_466560 endp