Java 8 引入了如下小数舍入行为更改:当值非常接近时使用 java.text.NumberFormat 和 java.text.DecimalFormat 类上的 format 方法,从而正好符合格式化模式中指定的舍入位置。 此更改将影响具有不准确的二进制数字表示法的数字。
例如,计算机可达到的 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 + ") returns \"" + myStr + "\". Expecting \"0.805\"."); nf.setMaximumFractionDigits(2); aDouble = 0.015d; myStr = nf.format(aDouble); System.out.println("format(" + aDouble + ") returns \"" + myStr + "\". Expecting \"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 + "\". Expecting \"55.5%\"."); } |
如果您使用 Java 7 来调用该代码,那么将显示以下输出:
format(0.8055) 返回了“0.806”。 期望“0.805”。在 Java 8 中,将显示以下输出:
format(0.8055) 返回了“0.805”。 期望“0.805”。请注意该行为更改,因为它可能会影响程序输出。 JDK-7131459 错误报告提供了更多信息并显示了多个相关报告,包括针对 Java 8 的错误报告(将此错误报告为回归)。
有关受影响类的更多信息,请参阅以下资源: