原始双值等于取决于幅度?

时间:2011-10-05 23:31:35

标签: java

我必须检查两个双精度值是否相等,包括幅度和精度。我遇到一个奇怪的场景,其中原始的双等于检查不一致并且取决于值的大小。

我使用的Java版本:

java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode, sharing)

我的代码:

public class Test{
     public static void main(String args[]) throws Exception{
         String val1 = "15.999999999999999";
         String val2 = "16";
         String val3 = "16.999999999999999";
         String val4 = "17";
         double d1 = Double.parseDouble(val1);
         double d2 = Double.parseDouble(val2);
         double d3 = Double.parseDouble(val3);
         double d4 = Double.parseDouble(val4);
         System.out.println(val1 + "=" + val2 + "? ===>" + (d1==d2));
         System.out.println(val3 + "=" + val4 + "? ===>" + (d3==d4));
     }
}

输出:

15.999999999999999=16? ===>false
16.999999999999999=17? ===>true

3 个答案:

答案 0 :(得分:3)

您尝试做的事情不适用于您在此处可以阅读的各种无聊和复杂的原因:http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

除非你要比较双打的比特表示(可能有洞察力,也可能没有洞察力),否则你总是需要某种epsilon值,即处理数字的浮点表示时的误差范围。类似的东西:

boolean doublesAreEqual(double d1, double d2)
{
    double d = d1 / d2;
    return (Math.abs(d - 1.0) < 0.00001 /* epsilon */);
}

答案 1 :(得分:1)

浮点数是近似值。它们可能有一组有限的离散值。通过解析字符串创建浮点数时,将选择最接近的浮点值来表示它。

最接近15.999999999999999的双精度数为15.999999999999998,而不是16.0,因此比较不相等。但是17.0是最接近16.999999999999999的两倍,所以他们比较相等。

答案 2 :(得分:0)

在比较double或float值时不要使用==。

改为使用Double.compare http://download.oracle.com/javase/6/docs/api/java/lang/Double.html

和Float.compare for floats。