Lets compare the following two:
long ftoint(float x) { unsigned int e = (0x7F + 31) - ((* (unsigned int*) &x & 0x7F800000) >> 23); unsigned int m = 0x80000000 | (* (unsigned int*) &x << 8); return int((m >> e) & -(e < 32)); } long ftointfast(float x){ return x; }
Clang with -O3 produces:
ftoint(float): # @ftoint(float) movd eax, xmm0 mov ecx, eax shr ecx, 23 movzx edx, cl mov ecx, 158 sub ecx, edx shl eax, 8 or eax, -2147483648 shr eax, cl xor edx, edx cmp ecx, 32 cmovb edx, eax movsxd rax, edx ret ftointfast(float): # @ftointfast(float) cvttss2si rax, xmm0 ret
I am not fluent in assembly, but I am certain that you cannot get it faster than a single instruction.
std::floor(arg) computes the largest integer value not greater than arg. It returns a floating point value. If you do not need a floating point value but only the integer then you do not need std::floor. You also do not need to compare your solution to std::floor because it does something you don't need. And of course you can just write (assuming x actually fits in the range of long):
long y = x;
or to be explicit
long y = static_cast<long>(x);
int y = x;??ftointroutine also has undefined behavior.int y = x;as a single instruction:vcvttss2si eax, xmm0. That seems pretty fast.floorfromcmathbeing actually useful. The reason is that it returns afloat. If it would return an integer, I have no clue what would it be good for in c++, you dont needfloor(or some other fancy stuff) to convert afloatto anintfloat/doubledirectly to anint/longor have it implicitly converted? That'll be the fastest.