Java 7和Java 8之间的舍入不一致是一个错误吗? [英] Is inconsistency in rounding between Java 7 and Java 8 a bug?
问题描述
我发现 中的舍入不一致这是我的测试用例:
I'm seeing inconsistencies in rounding in the DecimalFormat
class between java 7 and java 8. Here is my test case:
import java.text.DecimalFormat;
public class DecimalFormatTest {
public static void main(String[] args) {
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance();
format.setDecimalSeparatorAlwaysShown(true);
format.setMinimumFractionDigits(1);
format.setMaximumFractionDigits(1);
System.out.println(format.format(83.65));
}
}
在Java(TM)SE运行时环境(构建1.7) .0_51-b13)输出为:
In Java(TM) SE Runtime Environment (build 1.7.0_51-b13) the output is:
83.6
在Java(TM)SE运行时环境(版本1.8.0-b132)中,输出为:
In Java(TM) SE Runtime Environment (build 1.8.0-b132) the output is:
83.7
这是一个回归错误吗?或者随着Java 8的发布,舍入规则发生了变化?
Is this a regression bug? Or were the rounding rules changed with the release of Java 8?
推荐答案
看起来这是JDK中一个长期存在的错误7终于修复了。参见例如:
It looks like this was a long-standing bug in JDK 7 that was finally fixed. See for example:
- https://bugs.openjdk.java.net/browse/JDK-8029896
- https://bugs.openjdk.java.net/browse/JDK-7131459
有一个计划草案,向JDK 8提供以下建议,解释了这个问题:
There is a draft plan to provide the following advisory with JDK 8 which explains the issue:
-------------------------------------------------- -------------------区域:核心库/ java.text
--------------------------------------------------------------------- Area: Core Libraries / java.text
概要 :修复了JDK7的错误舍入行为。当值非常接近准确位于格式化模式中指定的
舍入位置的平局时,NumberFormat / DecimalFormat format()方法的
舍入行为已更改
。
Synopsis: A wrong rounding behavior of JDK7 has been fixed. The rounding behavior of NumberFormat/DecimalFormat format() method has changed when value is very close to a tie sitting exactly at the rounding position specified in the formatting pattern.
不兼容的性质:行为
说明 :当使用NumberFormat / DecimalFormat类时,以前的JDK版本的
舍入行为在某些角落的
情况下是错误的。调用format()方法时,这个错误的行为发生时,
a值非常接近平局,而使用NumberFormat / DecimalFormat实例的模式指定
的舍入位置是
领带的位置。在这种情况下,错误的双
舍入或错误的非舍入行为发生。
Description: When using NumberFormat/DecimalFormat classes, the rounding behavior of previous JDK versions was wrong in some corner cases. This wrong behaviour happened when calling format() method with a value that is very close to a tie, while rounding position specified by the pattern of the NumberFormat/DecimalFormat instance used is exactly sitting at the position of the tie. In that case wrong double rounding or erroneous non-rounding behavior happened.
例如,使用默认推荐的 NumberFormatFormat
API
表格: NumberFormat nf = java.text.NumberFormat.getInstance()
跟随
nf.format(0.8055d)
,值 0.8055d
在计算机中记录为
0.8054999999999999378275106209912337362766265869140625
,因为此值无法以二进制格式精确表示。这里默认的
舍入规则是半偶数,并且在
JDK7中调用format()的结果是0.806的错误输出,而正确的结果是0.805
,因为由计算机记录在存储器中的值是低于平局。
As an example, while using default recommended NumberFormatFormat
API
form: NumberFormat nf = java.text.NumberFormat.getInstance()
followed
by nf.format(0.8055d)
, value 0.8055d
is recorded in the computer as
0.80549999999999999378275106209912337362766265869140625
since this value cannot be represented exactly in binary format. Here default
rounding rule is "half-even", and the result of calling format() in
JDK7 is a wrong output of "0.806", while correct result is "0.805"
since value recorded in memory by the computer is "below" the tie.
这个新行为也适用于所有可能由程序员选择的任何模式(非
默认模式)定义的舍入位置
。
This new behavior is also implemented for all rounding positions that might be defined by any pattern chosen by the programmer (non default ones).
RFE
7131459
这篇关于Java 7和Java 8之间的舍入不一致是一个错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!