我是"播放";通过尝试优化某些事物(较少的变量等(,使用快速逆sqrt函数。这是最后的代码:
float Q_rsqrt(float x) {
const float x2 = x * 0.5F;
uint_fast32_t i;
memcpy(&i, &x, sizeof(float));
i = 0x5f3759df - ( i >> 1 );
memcpy(&x, &i, sizeof(float));
return x * ( 1.5F - ( x2 * x * x ) );
}
首先,知道在我的体系结构中,uint_fast32_t
在64位上表示,float
在32位上表示是有用的。因此,在不同大小的可变类型上制作memcpy()
可能是令人惊讶的。我遇到的问题是,一旦代码被编译,每次用相同的参数调用这个函数都会给出相同的返回值:有时这个是负的,有时是正的(但总是具有相同的绝对值(。memcpy()
的作用是绕过以下代码的警告(取消引用类型的punned指针将打破严格的混叠规则((它完全按照要求工作(:
float Q_rsqrt_test(float x) {
const float xHalf = x * 0.5F;
const uint_fast32_t i = 0x5f3759df - ( (* ( uint_fast32_t * ) &x) >> 1 );
x = * ( float * ) &i;
return x * ( 1.5F - ( xHalf * x * x ) );
}
对于这段代码,我想说不存在类型大小的问题,因为源(在上面的链接上可见(已经使用了double type
,它在我的体系结构中用64位表示(而不是32位的float
(。
我真的不明白为什么我可以用第一个函数得到否定的答案。。。
谢谢你的帮助。
正如Barmar所说,将i初始化为0有效。我还认为最好避免去引用到另一个大小的类型(例如*(uint64_t *) &x
,其中x是浮点(。使用uint32_t
的解ferecing,然后将结果正确地转换为64位变量,可能会更好。