Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 7和Java 8之间的舍入不一致是一个错误吗?_Java_Rounding - Fatal编程技术网

Java 7和Java 8之间的舍入不一致是一个错误吗?

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

我发现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 -> 100.00
99.9990 ->  99.99
JDK 8有一个提供以下咨询的计划草案,解释了这个问题:

---------------------------------------------------------------------区域:核心库/java.text

简介:修正了JDK7的错误舍入行为。这个 NumberFormat/DecimalFormat format()方法的舍入行为已发生变化 当值非常接近正好位于同一位置的平局时发生更改 在格式化模式中指定的舍入位置

不兼容的性质:行为

说明:使用NumberFormat/DecimalFormat类时 以前JDK版本的舍入行为在某些方面是错误的 案例。使用调用format()方法时发生此错误行为 在指定舍入位置时,非常接近平局的值 通过使用NumberFormat/DecimalFormat实例的模式 正好坐在领结的位置上。那样的话,错了 发生舍入或错误的非舍入行为

例如,在使用默认推荐的
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仍在进行中。可能是因为它工作不正常,所以也重新打开了。我可以稍后提供一个测试用例。