简体   繁体   中英

Fastest way to convert a float to int in C++

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM