What is the fastest and most efficient way to convert a float to an integer in c++ (rounding toward zero)? is it
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));
}
?
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);
Probably with
long ftoint(float x)
{
return (long)x;
}
(or static_cast
if you hate C-style casts)
In fact, you don't need a function. You can just write the cast.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.