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

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

我用过的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 

您正在尝试做的事情不适用于您在此处可以阅读的各种无聊和复杂的原因: 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 */); } 

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

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

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

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

和Float.compare浮动。