问题描述及方案

  • 假设我们在做电商项目,在进行计算时这个丢失精度在产品价格计算就会出现问题,很有可能造成我们手里有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. Oracle12c多租户CDB 与 PDB 参数文件位置探讨、查询 CDB 与 PDB 不同值的参数

    一. Oracle12c多租户CDB 与 PDB 参数文件位置CDB的参数文件依然使用12c以前的SPIFLE,pdb的参数文件不会出现在SPFILE中,而是直接从CDB中继承,如果PDB中有priv ...

  2. 计算进程消费cpu和内存

    Linux下没有直接可以调用系统函数知道CPU占用和内存占用.那么如何知道CPU和内存信息呢.只有通过proc伪文件系统来实现. proc伪文件就不介绍了,只说其中4个文件.一个是/proc/stat ...

  3. ThinkPHP5.0中Redis的使用和封装(原创)

    Redis是一种常用的非关系型数据库,主要用作数据缓存,数据保存形式为key-value,键值相互映射.它的数据存储跟MySQL不同,它数据存储在内存之中,所以数据读取相对而言很快,用来做高并发非常不 ...

  4. Spring Boot Dubbo applications.properties 配置清单

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 与其纠结,不如行动学习.Innovate ,And out execute ! 』 本文 ...

  5. C#中对于变量的声明和初始化

    C#变量初始化是C#强调安全性的另一个例子.简单地说,C#编译器需要用某个初始值对变量进行初始化,之后才能在操作中引用该变量.大多数现代编译器把没有初始化标记为警告,但C#编译器把它当作错误来看待. ...

  6. Bash Scripting Learn Notes

    References: [1] http://www.tldp.org/LDP/Bash-Beginners-Guide/html/ 1. Executing programs from a scri ...

  7. MindNode for mac 思维导图

    绘制思维导图 下载地址 链接: https://pan.baidu.com/s/1o7NBzmU 密码: mu3f

  8. 2017年PHP培训机构排名

    2017年PHP培训机构排名 PHP培训属于IT培训的一个领域.随着互联网的火爆,PHP也变得异常火爆.通过对PHP培训机构的调查与了解,到底学员选择哪一家的PHP培训机构才能够学到真正的技术,PHP ...

  9. CoreCLR源码探索(六) NullReferenceException是如何发生的

    NullReferenceException可能是.Net程序员遇到最多的例外了, 这个例外发生的如此频繁, 以至于人们付出了巨大的努力来使用各种特性和约束试图防止它发生, 但时至今日它仍然让很多程序 ...

  10. Spring MVC动态切换数据源(多数据库类型)

    最近由于项目需求,需要将Sql Server 和 Mysql 两种数据库整合到一个项目,项目的用到的框架是SSM. 因此尝试了利用AOP切面来切每次执行的Servcie方法,根据Service所在的包 ...