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。

为什么用EITHER(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存储到temp变量中。像这样

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未被修改,将产生正确的结果。

10-02 17:41