public static float sqrt(float x) {
float xhalf = 0.5f*x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i); <----- EDIT: x is modified here (smh)
x = x*(1.5f - xhalf*x*x);
return x*2;
}
public static float sqrtWITHOUTXHALF(float x) {
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i);
x = x*(1.5f - (x/2)*x*x); // <---- replaced with parens
return x*2;
}
例如,顶部的 sqrt(2( 是 1.4139,而第二个是 1.8855。
为什么用 (x/2( 或 (x*0.5f( 替换 xhalf 变量会更改结果值?
编辑:哇,我没有看到这一点,这对我来说非常愚蠢。不过我不会删除这个,叹息。
您需要
将第一个修改为如下所示(以获得 1.8855(
public static float sqrt(float x) {
int i = Float.floatToIntBits(x); //initialize i
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i); //modify x
float xhalf = 0.5f*x; //then initialize xhalf
x = x*(1.5f - xhalf*x*x);
return x*2;
}
它产生了 1.8855,所以现在两者都生产相同的东西。然而,这是不正确的答案。所以这就是你得到不同结果的原因。
更新:如果您希望第二个产生正确的结果,您可以将 x 存储到临时变量中。喜欢这个
public static float sqrtWITHOUTXHALF(float x) {
float _x = x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i);
x = x*(1.5f - (_x/2)*x*x); // <---- replaced with parens
return x*2;
}
现在,新变量_x
未修改,将产生正确的结果。