John Carmack在Quake III源代码中有一个特殊函数可以计算浮点数的平方根倒数,速度比普通的(float)(1.0/sqrt(x))
快4倍,其中包括奇怪的0x5f3759df
常量。请见下面的代码。有人可以逐行解释一下这里到底发生了什么,以及为什么这比常规实现要快得多吗?
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) );
#ifndef Q3_VM
#ifdef __linux__
assert( !isnan(y) );
#endif
#endif
return y;
}
i = * ( long * ) &y;
中,为什么要将 y 的地址作为长整型指针来获取,然后再将其解除引用? - Nubcakey
是一个float
,这里将其强制转换为整数。这是不安全的,因为它违反了C语言的严格别名规则。在C99中使用union
,或在C89 / C++中使用memcpy
可以遵循语言规则做同样的事情,并且至少在现代优化编译器中编译结果相同。 - Peter Cordes