在使用 时DecimalFormat
,我对它在使用定点模式舍入数字时的行为感到困惑。为了使事情更具体:
double n = 2082809.080589735D;
// Output the exact value of n
System.out.println("value: " + new BigDecimal(n).toPlainString());
System.out.println("double: " + n);
DecimalFormat format = new DecimalFormat("0.00000000");
System.out.println("format: " + format.format(n));
System.out.println("format (BD): " + format.format(new BigDecimal(n)));
此代码段的输出是:
value: 2082809.080589734949171543121337890625
double: 2082809.080589735
format: 2082809.08058974
format (BD): 2082809.08058973
从第一行输出中,我们注意到实际值低于2082809.08058973
和2082809.08058974
( ...49...
)之间的中点。尽管如此,DecimalFormat
在提供double
参数时将值向上舍入。
其他值向下舍入:
value: 261285.2738465850125066936016082763671875
double: 261285.273846585
format: 261285.27384658
format (BD): 261285.27384659
这并非在所有情况下都会发生:
value: 0.080589734949171543121337890625
double: 0.08058973494917154
format: 0.08058973
format (BD): 0.08058973
value: 0.2738465850125066936016082763671875
double: 0.2738465850125067
format: 0.27384659
format (BD): 0.27384659
在我看来,a 的格式化字符串double
是使用半偶数舍入舍入的,该舍入基于一个不精确的十进制值,该十进制值是由 的行产生的Double.toString()
,而不是所讨论的实际数学值double
。当格式化的精度非常接近(或超过)double
类型提供的精度时,事情开始变得有些随机。
在上面介绍的所有情况下,格式化相应的BigDecimal
似乎可以按预期执行舍入。
DecimalFormat
在这种情况下,我找不到任何描述正确行为的规范。
这种行为是否记录在某处?
从正确性的角度来看,将实际数学值四舍五入不是更可取吗?
我知道写作的人
1.0...35
会(天真地?)期望它被四舍五入1.0...4
,但1.0...35
甚至可能无法用 Java 中可用的任何原始数据类型表示......
编辑:
我已经向 Oracle 提交了一份报告——希望他们能够解决或澄清这个问题。