问题描述及方案

  • 假设我们在做电商项目,在进行计算时这个丢失精度在产品价格计算就会出现问题,很有可能造成我们手里有9.99元然后后面会有一堆9,但是呢这些钱无法购买一个10元的商品。

    在某些编程语言中有专门处理货币的类型,但是Java没有,不过没关系我们可以通过BigDecimal来解决这个问题。
  • 下面我们来看几个例子。

testOne

  • 这个呢就是Java本身对于浮点计算的时候会丢失精度,一定要注意,一定要注意,它所引起的事情呢基本没有小事,如果在线上订购量大的话,会引起大的故障,

    可能会导致下不了订单或是对账出现问题

testTwo

  • 当使用BigDecimal后结果就更乱了,比test1结果还可怕又长又乱,它算出来的数比0.06是多的还是刚才那个意思,假设我们现在,

    银行卡里面有0.06元然后我买的两个商品,分别是0.05元和0.01,当我下单的时候如果没有做处理那么他需要付的是0.06000000000000000298372437868010820238851010799407958984375

    这就导致余额不够,订单无法下。这还没解决,不要紧,接着看

testThree

  • 用String的BigDecimal构造器,这个结果就是我们想要的,本身呢BigDecimal这个类型是用它来解决这个问题但是我们在选择用它的时候,一定一定一定

    要选择它的Spring构造器一旦不用就像test2一样会发生严重过的精度问题,这个原则在《Effective Java》这本书中也有说,是说这个原则如果float和double只能用来做

    科学计算或者工程计算,但是在商业计算中我们要用BigDecimal。

源码分析

1.说明

  • 在java.math包中找到API类BigDecimal,然后找到BigDecimal(double)构造方法

  • 源代码里写的很明白这个结果和这个构造器就会产生这个种问题它是无限接近于这么一个数这个构造器呢不是正好的,而是等于0.1

2.用法

  • 如果用这个构造器呢,把它转成String,用Double的toString(double),里面放double然后用BigDecimal(String)这个String去构造,

    也就是说如果要用的话,就把它转成String然后在选择用BigDecimal的String构造器去获得结果。另外3个这里就不讲了自己去看;
  • 为了方便我们可以把它写成一个util类,日后我整理完了会把它放在GitHub上。

原文:http://www.godql.com/blog/2017/05/17/Precision/

作者:Dr.Lester

Java数值避免浮点型计算丢失精度问题的更多相关文章

  1. Java 数值类型以及计算

    前段时候写了一个对外提供的接口,其中有一个数值校验的计算.在测试的过程中发现5.6-1.6 != 4,在反复的测试过程中发现double类型的数值为有精度丢失的现象,看来还是基础知识不牢固,所以就在网 ...

  2. js 计算丢失精度问题

    计算时用parseFloat,计算完后转换成Number对象 var ytje = parseFloat("0.03"); var handlecharge = parseFloa ...

  3. Java使用BigDecimal解决浮点型运算丢失精度的问题

    @Test public void test1(){ System.out.print(0.05+0.01); } @Test public void test2(){ BigDecimal b1 = ...

  4. JS 浮点型计算的精度问题 推荐的js 库 推荐的类库 Numeral.js 和 accounting.js

    推荐的类库 Numeral.js 和 accounting.js 文章来自 http://www.css88.com/archives/7324#more-7324

  5. Java浮点数float,bigdecimal和double精确计算的精度误差问题总结

    (转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...

  6. 【转】JAVA程序中Float和Double精度丢失问题

    原文网址:http://blog.sina.com.cn/s/blog_827d041701017ctm.html 问题提出:12.0f-11.9f=0.10000038,"减不尽" ...

  7. 金融项目java开发_BigDecimal(解决计算精度问题)

    当使用double进行商业运算时,double计算会丢失精度.可以使用BigDecimal进行计算. import java.math.BigDecimal; import org.junit.Tes ...

  8. 关于java的Long 类型到js丢失精度的问题

    写代码碰到一个bug, 现象是 后台Java返回的18位的Long类型的数据,到前台丢失了精度.  查了一下,原因是 java的Long类型是18位, 而 js的Long类型(虽然没有明确定义的Lon ...

  9. Long类型转json时前端js丢失精度解决方案

    一.问题背景 Java后端开发过程中,尤其是id字段,因数值太大,通过json形式传输到前端后,在js解析时,会丢失精度. 如果对精度丢失没有什么概念,可以看一个知乎的帖子,来感受一下:https:/ ...

随机推荐

  1. 谷歌广告Admob在cocos2dx上通过回调实现底部Banner

    首先说明我的开发平台,以免由于平台问题造成不必要的误解: cocos2dx-3.4 ndk-r9d eclipse Admob是谷歌官方广告,已经集成在google_play_service_lib包 ...

  2. GitHub的实践

    GitHub的实践 2017-05-08,晴,来小米已经一周的时间了,感谢领导能给我一周的时间来熟悉 ubuntu.spring boot.maven.docker.github .大家会问,这些不都 ...

  3. ArcGIS 网络分析[1.5] 使用点线数据一起创建网络数据集(如何避免孤立点/点与线的连通性组合结果表)

    ArcGIS中最基本的三种矢量数据是什么?点线面. 网络中除了路网之外,还会有地物点. 如上图,我们在建立网络数据集的时候,作为实验,当然可以只是公路网.但是在大型的决策任务中,网络数据集就不只是公路 ...

  4. 详谈JAVA中的file类与IO流

    File类 位置于java.io包构造方法:File(String parent, String child)new file("d:\\","a.txt") ...

  5. H5与客户端联调

    进行H5移动端开发时,我们可以使用谷歌浏览器的设备工具栏进行,此方法实时方便快速,但这也是有限的,当我们需要在特定机型特定系统或者在webview中调试时,这种方法就显得很吃力了. 安卓: 一.与安卓 ...

  6. 使用redis做mybaties的二级缓存(2)-Mybatis 二级缓存小心使用

    Mybatis默认对二级缓存是关闭的,一级缓存默认开启: 下面就说说为什么使用二级缓存需要注意: 二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到 ...

  7. java.util.Properties工具类

    import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import ...

  8. 开关调色新世界BP2888电源解决方案

    LED智能方案经过几年的拼杀,已经风靡照明界.但人们渐渐发现,对照明来说,一味追求花哨的功能并不被市场所认同,而其中开关调色,以其简单易操作的特点,已逐步融入广大消费者的生活习惯中.对吸顶灯,面板灯等 ...

  9. 用css3过滤做遮罩效果

    <!DOCTYPE html><html ng-app="myApp" ng-controller="myController">< ...

  10. Java学习笔记——MySQL开放3306接口与设置用户权限

    系统Ubuntu16.04 LTS 1.开放3306端口查看端口状态:netstat -an|grep 3306tcp        0      0 127.0.0.1:3306          ...