如果您查看这个非常好的页面:
http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
你会看到这个程序:
#define SQRT_MAGIC_F 0x5f3759df
float sqrt2(const float x)
{
const float xhalf = 0.5f*x;
union // get bits for floating value
{
float x;
int i;
} u;
u.x = x;
u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
return x*u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy
}
我的问题是:是否有任何特殊原因导致其未实现为:
#define SQRT_MAGIC_F 0x5f3759df
float sqrt2(const float x)
{
union // get bits for floating value
{
float x;
int i;
} u;
u.x = x;
u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0
const float xux = x*u.x;
return xux*(1.5f - .5f*xux*u.x);// Newton step, repeating increases accuracy
}
因为,从反汇编中,我看到一个MUL
更少。是否有任何目的让xhalf
出现?
答案 0 :(得分:4)
当使用最后一行链接在一起的乘法器作为中间结果保存在80位寄存器中时,使用80位寄存器的传统浮点数学可能更准确。
上层实现中的第一个乘法与后面的整数数学并行发生,它们使用不同的执行资源。 另一方面,第二个功能看起来更快,但很难说它是否真的是由于上述原因。 此外, const float xux = x * u.x; 语句将结果减少回32位浮点数,这可能会降低整体精度。
您可以头对头测试这些函数,并将它们与math.h中的 sqrt 函数进行比较(使用double not float)。通过这种方式,您可以看到哪个更快,哪个更准确。