Why does Math.round(0.49999999999999994) return 1?
在下面的程序中,您可以看到每个略小于
1 2 3 4 5 6 7 8 9 |
印刷品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 10.5 rounded is 11 10.499999999999998 rounded is 10 9.5 rounded is 10 9.499999999999998 rounded is 9 8.5 rounded is 9 8.499999999999998 rounded is 8 7.5 rounded is 8 7.499999999999999 rounded is 7 6.5 rounded is 7 6.499999999999999 rounded is 6 5.5 rounded is 6 5.499999999999999 rounded is 5 4.5 rounded is 5 4.499999999999999 rounded is 4 3.5 rounded is 4 3.4999999999999996 rounded is 3 2.5 rounded is 3 2.4999999999999996 rounded is 2 1.5 rounded is 2 1.4999999999999998 rounded is 1 0.5 rounded is 1 0.49999999999999994 rounded is 1 0.4999999999999999 rounded is 0 |
我正在使用Java 6更新31。
摘要P></
在Java 6(和presumably earlier),要实现
the问题P></
确切的说因为是0.49999999999999994 0.5 + 1是双精度:P></
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void print(double d) { System.out.printf("%016x ", Double.doubleToLongBits(d)); } public static void main(String args[]) { double a = 0.5; double b = 0.49999999999999994; print(a); // 3fe0000000000000 print(b); // 3fdfffffffffffff print(a+b); // 3ff0000000000000 print(1.0); // 3ff0000000000000 } |
这是因为0.49999999999999994 has a指数比0.5小时,知道他们的增值,其尾数移is,and the ULP变得大。P></
the solutionP></
因为Java 7(for example,OpenJDK恩thus implements):4P></
1 2 3 4 5 6 | public static long round(double a) { if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5 return (long)floor(a + 0.5d); else return 0; } |
<副>1。http:/ / / / 6 docs.oracle.com javaSE /文档/ / / / math.html Java API #圆朗28double 29 % %></分P></
<副>2。http:/ / / / bugs.java.com bugdatabase _ bug.do视图?_ id = 6430675 BUG(这simonnickerson for this to @测距)></分P></
<副>3。http:/ / / / docs.oracle.com javaSE 7 /文档/ / / / math.html Java API #圆朗28double 29 % %></分P></
<副>4。http:/ / / / / grepcode.com文件repository.grepcode.com JDK Java /根/ / / / 7u40 OpenJDK的B43 - Java /郎/ math.java # math.round 28double 29 % %></分P></
this appears to be known臭虫(臭虫在Java 6430675 surprising行为:math.round has been for which has 0x1.fffffffffffffp-2)在Java 7固定。P></
6:在JDK的源代码P></
1 2 3 |
7:在JDK的源代码P></
1 2 3 4 5 6 7 8 | public static long round(double a) { if (a != 0x1.fffffffffffffp-2) { // a is not the greatest double value less than 0.5 return (long)Math.floor(a + 0.5d); } else { return 0; } } |
when the value is 0.49999999999999994d JDK 6,因此,它将返回1楼和呼叫,但在JDK 7,检查是否
你可以尝试0.49999999999999999d,which will返回1,but not because this is the Greatest 0,less双值0.5。P></
我有一样的JDK 1.6由32位,64位Java在线但我有7 0 0 rounded 0.49999999999999994 which is for the last is not印刷和在线。在VM的问题似乎是,不管一个人多,使用浮动点,你应该指望有什么不同的结果在不同的网络环境(位或32的CPU,64位模式)。P></
当使用布尔矩阵,
x64输出:P></
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 10.5 rounded is 11 10.499999999999998 rounded is 10 9.5 rounded is 10 9.499999999999998 rounded is 9 8.5 rounded is 9 8.499999999999998 rounded is 8 7.5 rounded is 8 7.499999999999999 rounded is 7 6.5 rounded is 7 6.499999999999999 rounded is 6 5.5 rounded is 6 5.499999999999999 rounded is 5 4.5 rounded is 5 4.499999999999999 rounded is 4 3.5 rounded is 4 3.4999999999999996 rounded is 3 2.5 rounded is 3 2.4999999999999996 rounded is 2 1.5 rounded is 2 1.4999999999999998 rounded is 1 0.5 rounded is 1 0.49999999999999994 rounded is 0 |
答案hereafter is of the />方法strictmath.round are the {数学定义,operationally asP></
1 |
双Arguments for。我厂usually expected this定义as the result of,它给surprising Rather比0,1,0x1.fffffffffffffp-2(0.49999999999999994 for)。P></
最伟大的0.49999999999999994 is the value less浮点值0.5。as a浮点值literal hexadecimal its is which is equal to 0x1.fffffffffffffp-2,(2 - 2 - 2 * 2(52)。=(0.5~2 54)。therefore the value of the sum,精确P></
1 | (0.5 - 2^54) + 0.5 |
是1 - 2 54。This is between the已经两相邻的浮点数字(1 - 2和1 53)。在IEEE 754 arithmetic to the used最近甚至rounding回合模式java模式,当浮点结果是接近两inexact of the,表示浮点值which must be returned the result支架精确值;如果都是equally Close the last one which is its returned零位。这房子在正确的返回值(1)is from the less not the Greatest,值1。P></
while the method is defined as the operating on this is,甚surprising输入行为规范;the amended to something like是"to the closest桑圆长,rounding关系会跟进,"which allow the to be changed on this输入的行为。P></