舍入误差不是随机的,其实现方式会尝试将误差最小化。这意味着有时错误不可见,或者没有错误。
例如不完全是 但正是0.1
0.1
new BigDecimal("0.1") < new BigDecimal(0.1)
0.5
1.0/2
此程序显示所涉及的真实值。
BigDecimal _0_1 = new BigDecimal(0.1);
BigDecimal x = _0_1;
for(int i = 1; i <= 10; i ++) {
System.out.println(i+" x 0.1 is "+x+", as double "+x.doubleValue());
x = x.add(_0_1);
}
指纹
0.1000000000000000055511151231257827021181583404541015625, as double 0.1
0.2000000000000000111022302462515654042363166809082031250, as double 0.2
0.3000000000000000166533453693773481063544750213623046875, as double 0.30000000000000004
0.4000000000000000222044604925031308084726333618164062500, as double 0.4
0.5000000000000000277555756156289135105907917022705078125, as double 0.5
0.6000000000000000333066907387546962127089500427246093750, as double 0.6000000000000001
0.7000000000000000388578058618804789148271083831787109375, as double 0.7000000000000001
0.8000000000000000444089209850062616169452667236328125000, as double 0.8
0.9000000000000000499600361081320443190634250640869140625, as double 0.9
1.0000000000000000555111512312578270211815834045410156250, as double 1.0
注意:这稍微偏离了一点,但是当您到达位时,必须向下移动一个位以适应53位限制,并且错误将被丢弃。同样,错误会爬回 for 和 for,但 for 会丢弃该错误。0.3
0.4
0.6
0.7
0.8
1.0
添加5次应该累积错误,而不是取消它。
出现错误的原因是由于精度有限。即 53 位。这意味着,随着数字越来越大,它使用更多的位,位必须从末端掉下来。这会导致四舍五入,在这种情况下,这对您有利。
当获得较小的数字时,您可能会得到相反的效果,例如: =>,您会看到比以前更多的错误。0.1-0.0999
1.0000000000000286E-4
这方面的一个例子是为什么在Java 6中为什么Math.round(0.49999999999999999994)返回1在这种情况下,计算中丢失一位会导致答案有很大的不同。