一、问题

最近使用BigDecimal进行数值加减运算的时候踩了一个小坑:BigDecimal操作double、float数值时精度丢失。
举个例子:

    public static void main(String[] args) {float d1 = 1.2f;float d2 = 2.1f;BigDecimal b1 = new BigDecimal(d1);BigDecimal b2 = new BigDecimal(d2);System.out.println(b1.add(b2));}

理想输出结果是3.3,实际上输出结果是3.2999999523162841796875。如果这个数乘以1000000000,这样就可能造成公司损失成千上万的金额,仅仅是由于精度丢失造成的。

我们知道,Java简单类型不能精确进行的浮点数运算,️而BigDecimal就是用来对超过16位的数字进行精确的浮点数运算的,那么为什么刚刚举的例子中会出现精度丢失的情况呢?

下面是BigDecimal的构造方法文档的解释:

public BigDecimal(double val)
将 double 转换为 BigDecimal,后者是 double 的二进制浮点值准确的十进制表示形式。返回的 BigDecimal 的标度是使 (10scale × val) 为整数的最小值。

即:
new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

通过BigDecima的文档可以看出使用BigDecimal的构造函数进行封装Double、Float型数值的时候,实际创建的值与我们期望的值会出现误差,因此在进行运算时会出现精度的丢失。

二、如何避免

在使用的时候,有两种方法:

  • 使用new BigDecimal(String);
  • 使用BigDecimal.valuOf(Double);

1、new BigDecimal(String):

    public static void main(String[] args) {double d1 = 1.2;double d2 = 2.1;BigDecimal b1 = new BigDecimal(d1.toString());BigDecimal b2 = new BigDecimal(d2.toString());System.out.println(b1.add(b2));}

输出结果为:3.3

2、BigDecimal.valuOf(double)的使用:

    public static void main(String[] args) {double d1 = 1.2;double d2 = 2.1;BigDecimal b1 = BigDecimal.valueOf(d1);BigDecimal b2 = BigDecimal.valueOf(d2);System.out.println(b1.add(b2));}

输出结果为3.3.
我们可以看下源码:

    public static BigDecimal valueOf(double val) {return new BigDecimal(Double.toString(val));}

可以看到 BigDecimal.valueOf(double)其实就等同于new BigDecimal(String)。

所以以后使用BigDecimal进行计算的时候一定要注意精度问题,不然造成公司百万、千万损失的时候可不就只是几个小数点的问题了,需要被杀了祭天的,sad。。

BigDecimal操作double、float精度丢失问题相关推荐

  1. double java 精度丢失_java中double和float精度丢失问题及解决方法

    在讨论两位double数0.2和0.3相加时,毫无疑问他们相加的结果是0.5.但是问题总是如此吗? 下面我们让下面两个doubles数相加,然后看看输出结果: @Test public void te ...

  2. 关于double与float精度丢失问题~看完我明白了☆

    今天刷面试题时,看到了(精度丢失)这个问题,今天来通过参考资料,把它总结一下 目录 ①<精度丢失>长什么样? ②为什么会精度丢失? ③用BigDecimal类解决精度丢失的问题 ①< ...

  3. double类型精度丢失问题以及解决方法

    double类型精度丢失问题: (1)加法运算. public static void main(String[] args) {double number1 = 1;double number2 = ...

  4. Double计算精度丢失(金融入门知识点)

    Double计算精度丢失(金融入门知识点) 一.double精度丢失 二.为什么double会精度丢失 三.BigDecimal错误的用法 四.BigDecimal正确的用法 Double计算精度丢失 ...

  5. float,double等精度丢失问题

    来自MSDN的解释: http://msdn.microsoft.com/zh-cn/c151dt3s.aspx 为何浮点数可能丢失精度浮点十进制值通常没有完全相同的二进制表示形式. 这是 CPU 所 ...

  6. Java中double类型精度丢失的问题_double类型数据加减操作精度丢失解决方法_BigDecimal取整

    BigDecimal在用double做入参的时候,二进制无法精确地表示十进制小数,编译器读到字符串"0.0000002"和"1.0000002"之后,必须把它转 ...

  7. java中double类型精度丢失问题及解决方法

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源: https://blog.csdn.net/yacolsp ...

  8. double operator[](int i)_java中double类型精度丢失问题及解决方法

    原文链接:https://blog.csdn.net/yacolspace/article/details/78287394 double类型数据加减操作精度丢失问题 今天在项目中用到double类型 ...

  9. Float精度丢失处理方法

    项目开发过程中,有很多涉及到金额.款项类的输入框,前端输入后传递到后端接收,很多时候直接用Float,Double类型接收,数值不是很大时候没问题,精度不会出错,但是一般数值过大就会出现小数点精度丢失 ...

最新文章

  1. js中 let var const 的差异和使用场景
  2. cordova项目怎样修改版本号
  3. hdu 1050 Moving Tables
  4. vue-cli新建的项目webpack设置涉及的大部分插件整理
  5. 云技术-SaaS架构初步理解
  6. iOS多任务:suspend VS terminate
  7. springboot和ssm的区别
  8. 友商对于鸿蒙系统,谷歌新系统上线!鸿蒙面临生死线考验,华为喊话友商,被小米拒绝...
  9. linux u盘读取速度,linux dd命令测试U盘读写速度
  10. tny278功能参数_tny27-280中文资料.pdf
  11. st7789 旋转_有没有人调过 ST7789V驱动的显示屏啊
  12. 辗转相除法求最大公因数
  13. linpack测试软件,linpack
  14. linux 内核 浮点运算,ARM64与x86_64浮点运算精度比较
  15. 经典风险因子模型 对于中国股票市场定价解释能力初探
  16. Java char转成int的方法
  17. 百度云原生产品 6 月刊 | CCE 节点组支持配置多个备选机型、CCR 新增镜像加速功能
  18. Cesium开发使用GPU渲染
  19. 论文投稿指南——准研究生们建议早点发小论文
  20. 光棍节就要到了,要不要给你介绍个 python 对象?

热门文章

  1. Admin监控Sleuth链路追踪 skywalking链路追踪
  2. ubuntu 查看GPU的信息(nvidia 品牌)
  3. Ubuntu18/20安装配置Bochs2.6.9与编译运行GeekOS
  4. java中将字符串分割转为List
  5. 解决word提示安全模式打开问题
  6. 12步”教你iPhone程序开发
  7. CPA小课堂:MUJI(无印良品)申请破产保护,里面牵扯了什么?
  8. 【美团杯2020】114514 解题报告
  9. 好消息:无穷小与微积分牵手国内移动互联网
  10. web sql数据库存储位置