在 C++ 中将 float 转换为 int 的最快方法

Ran*_*dom 0 c++ performance type-conversion

在 C++ 中将浮点数转换为整数(向零舍入)的最快且最有效的方法是什么?是吗

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));
}
Run Code Online (Sandbox Code Playgroud)

for*_*818 6

我们来比较以下两个:

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; }
Run Code Online (Sandbox Code Playgroud)

带有 -O3 的 Clang 会产生:

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
Run Code Online (Sandbox Code Playgroud)

我不太擅长汇编,但我确信你不可能比一条指令更快地掌握它。

std::floor(arg) 计算不大于 arg 的最大整数值。它返回一个浮点值。如果您不需要浮点值而只需要整数,则不需要std::floor。您也不需要将您的解决方案与您的解决方案进行比较,std::floor因为它做了您不需要的事情。当然,你可以直接写(假设x实际上适合 的范围long):

long y = x;
Run Code Online (Sandbox Code Playgroud)

或明确表示

long y = static_cast<long>(x);
Run Code Online (Sandbox Code Playgroud)