Java 7和Java 8之间的舍入不一致是一个错误吗?
我发现java 7和java 8之间的类舍入不一致。以下是我的测试用例: DecimalFormatTest.java 在Java(TM)SE运行时环境(build 1.7.0_51-b13)中,输出为:Java 7和Java 8之间的舍入不一致是一个错误吗?,java,rounding,Java,Rounding,我发现java 7和java 8之间的类舍入不一致。以下是我的测试用例: DecimalFormatTest.java 在Java(TM)SE运行时环境(build 1.7.0_51-b13)中,输出为: 83.6 83.7 在Java(TM)SE运行时环境(build 1.8.0-b132)中,输出为: 83.6 83.7 这是一个回归错误吗?或者取整规则是随着Java8的发布而改变的?看起来这是JDK7中一个长期存在的错误,最终得到了修复。例如,见: 99.9989 -> 10
83.6
83.7
在Java(TM)SE运行时环境(build 1.8.0-b132)中,输出为:
83.6
83.7
这是一个回归错误吗?或者取整规则是随着Java8的发布而改变的?看起来这是JDK7中一个长期存在的错误,最终得到了修复。例如,见:
99.9989 -> 100.00
99.9990 -> 99.99
NumberFormatFormat
API时
表单:NumberFormat nf=java.text.NumberFormat.getInstance()
通过nf.格式(0.8055d)
,值0.8055d
被记录在计算机中作为
0.80549999999999999378275106209912337362766265869140625
,因为此值不能以二进制格式精确表示。这里默认
舍入规则为“半偶数”,并且是在中调用format()的结果
JDK7是一个错误的输出“0.806”,而正确的结果是“0.805”
因为计算机记录在内存中的值是“低于”领带的
此新行为也适用于所有舍入位置
可以由程序员选择的任何模式定义(非
默认值)
无线电频率
7131459
正如在对这个问题的其他回答中所提到的,JDK 8对问题中的
DecimalFormat
舍入进行了有意更改
然而,这些更改引入了一个真正的bug。例如:
99.9989 -> 100.00
99.9990 -> 99.99
简单地说,这演示了一种情况,较高的数字向下舍入,较低的数字向上舍入:
(x请参阅。我不关心BigDecimal
的实现,这是一种不一致的行为。您可以选择或,但不能同时选择两者。这应该得到解决。@2rs2ts:这与BigDecimal
的实现无关-它只是用来演示问题。问题是83.65
不能完全正确地解释mellamokb噢,我明白我的困惑了。谢谢你指出这一点。我不知道你为什么要向我抱怨JDK是如何工作的——我只是在传递我找到的信息。不管怎样,OP得到83.7的原因是因为计算机从技术上讲是在对数字进行四舍五入83.6500000000000568843418860801486968994140625
,它被正确地四舍五入到83.7。基本上,如果你想使用类似货币的值,那么就不要使用浮点类型。@2rs2ts因为83.65实际上不是83.65。新的行为是正确的。我想知道这会如何影响用java编写的数百万金融程序!!希望99999个程序使用大小数来赚钱,而不是双精度或浮点。@rupps-任何使用浮点的金融程序在此更改之前都被破坏了。我担心,如果这样一个程序存在,那么这种回归的责任应该完全落在程序员身上。我记得在70年代末的CS学位上,有人告诉我不要使用FP赚钱。甚至在60年代,这也是众所周知的。。。知道为什么它仍然标记为“正在进行中”吗:?我刚刚在oracle 8.0.45中进行了测试,我发现半向上舍入有问题。@david不知道为什么状态仍在进行中。如果您仍然对8u45有问题,您可能会看到JDK-7131459的效果(请参阅答案中的链接),这造成了有意和无意的差异。我在8u40中报告为已修复的错误仅纠正了无意的差异。您还可以查看我的修补程序项目中的一些错误。@david如果您在我的回答中导航到JIRA链接(而不是bugs.java.com),它们被标记为“已解决/已修复”是的,我知道-我想这可能是针对openjdk的,oracle jdk仍在进行中。可能是因为它工作不正常,所以也重新打开了。我可以稍后提供一个测试用例。