说我有以下代码:
double factor;
double num = 4.35;
BigDecimal y = new BigDecimal(num);
BigDecimal n = new BigDecimal(factor);
BigDecimal asBigDecimal = y.multiply(n);
double asDouble = num * factor;
System.out.println("Double: " + asDouble + "\tBigDecimal: " + asBigDecimal);
当我将factor
设置为以下各项时会发生这种情况:
factor = 1: Double: 4.35 BigDecimal: 4.3499999999999996447286321199499070644378662109375
factor = 10: Double: 43.5 BigDecimal: 43.4999999999999964472863211994990706443786621093750
factor = 100: Double: 434.99999999999994 BigDecimal: 434.9999999999999644728632119949907064437866210937500
factor = 1000: Double: 4350.0 BigDecimal: 4349.9999999999996447286321199499070644378662109375000
此外,当我将System.out.print(4.35 / 10);
作为单独的程序运行时,我在控制台中获得0.43499999999999994
。为什么乘以1,10和1000会在控制台中给出舍入答案(作为双打)?我理解浮点精度的基础知识,4.35不能完全以二进制形式表示,那么为什么4.35打印到控制台(asDouble)?为什么不乘以100或除以10自动舍入?
答案 0 :(得分:2)
有几件事正在发生。首先,二进制有舍入,然后有十进制舍入。
查看那些BigDecimal值的二进制表示(我使用了我的Decimal/Binary Converter):
factor = 1: 100.0101100110011001100110011001100110011001100110011 (52 bits)
factor = 10: 101011.011111111111111111111111111111111111111111111111 (53 bits)
factor = 100: 110110010.11111111111111111111111111111111111111111111011 (56 bits)
factor = 1000: 1000011111101.1111111111111111111111111111111111111111100111 (59 bits)
因子1和10的结果不是二进制四舍五入;它们是<= 53位。打印为17位十进制数字,分别为4.35和43.5。
因子100和1000的结果是四舍五入的。因子100结果向下舍入到该值,因为位54是0:
factor = 100: 110110010.11111111111111111111111111111111111111111111 (53 bits)
以十进制表示,即434.99999999999994315658113919198513031005859375。圆为17位,为434.99999999999994。
因子1000结果被四舍五入到该值,因为位54及以上是> 1/2 ULP:
factor = 1000: 1000011111110
那是4350。