网站可以用什么做,安阳区号是什么,服装设计软件app下载,wordpress 帮助插件1.背景 1.10.1 1.2000000000000002 发现上面计算的值竟然和数学计算不一致
2. 问题
计算机是通过二进制计算的#xff0c;如果我们在二进制的视角来看待上面问题#xff0c;就很容易发现问题了。 例如#xff1a;把「0.1」转成二进制的表示#xff0c;然后还原成十进制0.1 1.2000000000000002 发现上面计算的值竟然和数学计算不一致
2. 问题
计算机是通过二进制计算的如果我们在二进制的视角来看待上面问题就很容易发现问题了。 例如把「0.1」转成二进制的表示然后还原成十进制就能看出问题。
3. 0.1转二进制
小数转二进制是通过除法进行的 0.1 1 ÷ 10 很简单二进制就是要算 1 ÷ 1010 最终0.1转二进制是0.0001100110011001100110011001100110011001100110011001101 4.转换成对应精度数值
float的精度为7~8位有效数字7位肯定能保证8位的值也存在。 double的精度为16~17位有效数字 所以 二进制展示 1.10.1 1.0011001100110011001100110011001100110011001100110100 十进制展示 1.10.1 1.2000000000000002 5.解决方案
针对浮点数丢失精度的问题我们可以通过BigDecimal来解决 new BigDecimal(double val) 该方法是不可预测的以0.1为例你以为你传了一个double类型的0.1最后会返回一个值为0.1的BigDecimal吗不会的原因在于0.1无法用有限长度的二进制数表示无法精确地表示为双精度数最后的结果会是0.100000xxx。 new BigDecimal(String val) 该方法是完全可预测的也就是说你传入一个字符串0.1他就会给你返回一个值完全为01的BigDecimal官方也表示能用这个构造函数就用这个构造函数叭。 BigDecimal.valueOf(double val) 第二种构造方式已经足够优秀可你还是想传入一个double值怎么办呢官方其实提供给你思路并且实现了它可以使用Double.toString(double val)先将double值转为String再调用第二种构造方式你可以直接使用静态方法valueOf(double val)。 总结将double转为BigDecimal的时候需要先把double转换为字符串然后再作为BigDecimal(String val)构造函数的参数这样才能避免出现精度问题。