我是小懒猴,人狠话不多,直接上才艺。
最近在生产上遇到一个精度问题,直接上结论
1、如果你使用浮点数作为参数调用BigDecimal的构造函数,Java会根据浮点数在内部的二进制表示进行转换。由于浮点数的二进制表示不能准确地表示所有十进制数,所以会出现精度损失和舍入误差
BigDecimal value = new BigDecimal(2.2); // 这会引入精度误差
System.out.println(value);
结果:
我们来一探究竟为何会产生如此原因
这就要说到浮点数二进制转bigdecimal的十进制如何计算了。
2进制转10进制过程举例 2.2 0.5
1、2.2
实际上,0.2的二进制表示是无限循环的小数:0.0011001100110011...(无限循环)。
要将其转换为十进制,我们可以使用以下步骤:
将二进制数的每个位上的数字与对应的权重相乘,并将结果相加。在二进制中,从右到左的位的权重是2的负幂次递减。
第一位小数:0 * 2^(-1) = 0
第二位小数:0 * 2^(-2) = 0
第三位小数:1 * 2^(-3) = 0.125
第四位小数:1 * 2^(-4) = 0.0625
第五位小数:0 * 2^(-5) = 0
第六位小数:0 * 2^(-6) = 0
依此类推,继续进行下去直到无限循环结束。
通过将所有计算得到的结果相加,我们可以得到:0 + 0 + 0.125 + 0.0625 + 0 + 0 + ...
由于小数部分是一个无限循环,我们无法准确地将其表示为有限的十进制数。然而,根据上述计算,我们可以得出0.2的二进制表示在十进制中是接近0.1875的值。
2、0.5
要将0.5的二进制表示转换为十进制,可以使用以下步骤:
0.5的二进制表示是0.1。
将二进制数的每个位上的数字与对应的权重相乘,并将结果相加。在二进制中,从右到左的位的权重是2的幂次递增。对于小数部分,从左到右的位的权重是2的负幂次递减。
第一位小数:1 * 2^(-1) = 0.5
将所有计算得到的结果相加:0.5
综上所述,0.1的二进制表示转换为十进制是0.5。