Java 8 引入了使用 format 方法对十进制数进行舍入的行为更改。
java.text.NumberFormat
与
java.text.DecimalFormat
类,当该值与一个平差非常接近时,正好坐落在格式化模式中指定的舍入位置。 此更改将影响具有不准确的二进制数字表示法的数字。
例如,计算机可达到的 0.015 的最接近二进制近似值为 0.01499999999999999944488848768742172978818416595458984375。 如果将该数字向下舍入为两位小数,
那么在 Java 8 中,答案为 .01,因为 .004999999.... 小于 .005。
在先前版本的 Java 中,答案是 0.02。
当使用 double 原语或 java.lang.Double 对象作为第一个参数来调用 NumberFormat 和 DecimalFormat format 方法时,此规则会标记对这些方法的调用。
以下示例显示了对这些 format 方法的使用。
public static void main(String[] args) {
java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
nf.setMaximumFractionDigits(3);
double aDouble;
String myStr;
aDouble = 0.8055d;
myStr = nf.format(aDouble);
System.out.println("format (" + aDouble + ") 返回 "+ myStr +"。 需要 "0.805\". ");
nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println("format (" + aDouble + ") 返回 "+ myStr +"。 需要 "0.01\". ");
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(1);
percent.setMaximumFractionDigits(1);
percent.setRoundingMode(RoundingMode.HALF_EVEN);
myStr = percent.format(0.5555);
System.out.println("format (0.5555) returns \"" + myStr + " \"。 需要 "55.5%". ");
}
如果您使用 Java 7 来调用该代码,那么将显示以下输出:
format(0.8055) 返回了“0.806”。 期望“0.805”。
format(0.015) 返回了“0.02”。 期望“0.01”。
format(0.5555) 返回了“55.6%”。 期望“55.5%”。
在 Java 8 中,将显示以下输出:
format(0.8055) 返回了“0.805”。 期望“0.805”。
format(0.015) 返回了“0.01”。 期望“0.01”。
format (0.5555) 返回了“55.5%”。 期望“55.5%”。
请注意该行为更改,因为它可能会影响程序输出。
JDK-7131459 错误报告提供了更多信息并显示了多个相关报告,包括针对 Java 8 的错误报告(将此错误报告为回归)。
有关受影响类的更多信息,请参阅以下资源: