快速浮点到整数转换(截断)

2023-11-23

我正在寻找一种方法来截断float进入一个int以快速且便携(IEEE 754)的方式。原因是因为在这个函数中 50% 的时间都花在了强制转换上:

float fm_sinf(float x) {
    const float a =  0.00735246819687011731341356165096815f;
    const float b = -0.16528911397014738207016302002888890f;
    const float c =  0.99969198629596757779830113868360584f;

    float r, x2;
    int k;

    /* bring x in range */
    k = (int) (F_1_PI * x + copysignf(0.5f, x)); /* <-- 50% of time is spent in cast */

    x -= k * F_PI;

    /* if x is in an odd pi count we must flip */
    r = 1 - 2 * (k & 1); /* trick for r = (k % 2) == 0 ? 1 : -1; */

    x2 = x * x;

    return r * x*(c + x2*(b + a*x2));
}

float->int 转换的缓慢主要发生在 x86 上使用 x87 FPU 指令时。为了进行截断,需要将 FPU 控制字中的舍入模式更改为舍入到零并返回,这往往非常慢。

当使用 SSE 而不是 x87 指令时,可以在不更改控制字的情况下进行截断。您可以使用编译器选项来执行此操作(例如-mfpmath=sse -msse -msse2在 GCC 中)或将代码编译为 64 位。

SSE3指令集有FISTTP指令转换为带截断的整数而不改变控制字。如果指示编译器采用 SSE3,则编译器可能会生成此指令。

或者,C99lrint()函数将使用当前舍入模式转换为整数(除非您更改它,否则舍入到最接近的值)。如果删除则可以使用它copysignf学期。遗憾的是,十几年过去了,这个功能仍然没有普及。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速浮点到整数转换(截断) 的相关文章

随机推荐