我正在寻找一种方法来截断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(使用前将#替换为@)