浮点数运算结果不精确,以及用String来构造BigDecimal进行浮点数精确计算
1.浮点数运算结果不精确
先看如下代码
System.out.println(1.0 - 0.8);
System.out.println(0.2 + 0.1);
System.out.println(1.0 - 0.8 == 0.2); //false
System.out.println(0.2 + 0.1 == 0.3); //false
输出结果为:
0.19999999999999996
0.30000000000000004
false
false
发现不是我们想要的正确结果,出现了1.0-0.8不等于0.2,0.2+0.1也不等于0.3的现象。
这是因为将java将double浮点数转换为64位二进制性,出现了精度损失。这跟IEEE754标准有关。可参考
https://www.iovi.com/post/2014-07-07-talk-about-double-in-java.html
2.用String来构造BigDecimal做浮点数的精确计算
//BigDecimal构造方法参数传入String,精准
BigDecimal b2 = new BigDecimal("1.0").subtract(new BigDecimal("0.8"));
System.out.println(b2);
System.out.println(new BigDecimal("0.1").add(new BigDecimal("0.1")).add(new BigDecimal("0.1")));
System.out.println(b2.equals(new BigDecimal(0.2))); //false
System.out.println(b2.equals(new BigDecimal("0.2"))); //true BigDecimal t2 = new BigDecimal("0.1");
System.out.println(t2);
输出结果为:
0.2
0.3
false
true
0.1
注意:只有用new BigDecimal(String)的构造方法,得到的才是浮点数的精确值。
以上第5行代码,用0.2这个double类型构造的BigDecimal已经丢失了精度,所以equals结果为false。
用new BigDecimal(Double)的构造方法,构造的BigDecimal不精确。如下:
//BigDecimal构造方法参数传入double类型,不精准
BigDecimal b = new BigDecimal(1.0).subtract(new BigDecimal(0.8));
System.out.println(b);
System.out.println(new BigDecimal(0.1).add(new BigDecimal(0.1)).add(new BigDecimal(0.1))); BigDecimal t = new BigDecimal(0.1);
System.out.println(t);
输出结果为:
0.1999999999999999555910790149937383830547332763671875
0.3000000000000000166533453693773481063544750213623046875
0.1000000000000000055511151231257827021181583404541015625
参考:
http://superivan.iteye.com/blog/963628
http://blog.csdn.net/xiaoyufu007/article/details/6654010
http://www.cnblogs.com/mingforyou/p/3344489.html
https://www.zhihu.com/question/26994476
浮点数运算结果不精确,以及用String来构造BigDecimal进行浮点数精确计算的更多相关文章
- 深入理解计算机系统(2.8)---浮点数的舍入,Java中的舍入例子以及浮点数运算(重要)
前言 上一章我们简单介绍了IEEE浮点标准,本次我们主要讲解一下浮点运算舍入的问题,以及简单的介绍浮点数的运算. 之前我们已经提到过,有很多小数是二进制浮点数无法准确表示的,因此就难免会遇到舍入的问题 ...
- 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
package com.minxinloan.utils; import java.math.BigDecimal; public class Arith { // 源文件Arith.java: /* ...
- js浮点数运算封装, 起因财务部分精确计算
目录 背景 具体代码 背景 项目中用到浮点数,Int 等 js中 Number类型比较多, 加上牵涉到财务软件, 前台js运算等. 有时候会出现精确度的问题 , 公共方法中有好事者写的方法. 此处拿来 ...
- js,java,浮点数运算错误及应对方法
js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...
- Java浮点数float,bigdecimal和double精确计算的精度误差问题总结
(转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...
- 浮点数运算的精度问题:以js语言为例
在 JavaScript 中整数和浮点数都属于 Number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此. 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00 ...
- Java之浮点数运算
浮点数运算和整数运算相比,只能进行加减乘除这些数值运算,不能做位运算和移位运算. 在计算机中,浮点数虽然表示的范围很大,但是浮点数有个非常重要的特点,就是浮点数常常无法精确表示 举例 浮点数0.1在计 ...
- JS浮点数运算Bug
JS浮点数运算Bug的解决办法(转) 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.0849999 ...
- JavaScript 浮点数运算 精度问题
JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本. //加减 <script type="text/javascript" lan ...
随机推荐
- 深入Dockerfile(一): 语法指南(转)
最近在学习K8S,发现这两篇文章还不错,转了过来 docker官方文档Dockerfile reference的笔记. 一.机制 1.1 构建 docker构建一个镜像,需要: Dockerfile文 ...
- SQl 执行效率总结
SQL执行效率总结 1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2 ...
- Servlet第一篇(Tomcat)
Tomcat 什么是Tomcat Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器. 为什么我们需要用到Tomcat 提供能够 ...
- AXI
1.Cachable和bufferable 一个Master发出一个读写的request,中间要经过很多Buffer,最后才能送到memory.这些Buffer的添加是为了outstanding,ti ...
- hdu 3065 AC自动机 标记数组不清零
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目里面要我们计算每种单词出现的次数,重叠的也要计算,那么我们在查找的时候不要把标记单词结尾的 ...
- 记忆化搜索 P1464 Function
题目描述 对于一个递归函数w(a,b,c) 如果a≤0 or b≤0 or c≤0就返回值1. 如果a>20 or b>20 or c>20就返回w(20,20,20) 如果a< ...
- intelliJ idea如何安装、配置
https://www.cnblogs.com/jajian/p/7989032.html
- WebSocket 实现链接 群聊(low low low 版本)
py 文件: """ 下载 gevent-websocket 0.10.1 基于Flask + geventWebSocket 建立连接,发送消息,实现群消息功能. &q ...
- crm开发之用户ModelForm定制和密码加密
写了这么多的定制 功能.终于可以定制一下了!因为是 stark 和 rbac 两个组建. 一起使用. 所以在这里,再记录一下.需要注意的点: 先放出 目录结构: 先从 stark 开始.使用star ...
- Linux平台生成awr报告
1.使用oracle用户登录应用服务器所使用的数据库所在的服务器 # su –oracle 2.输入env命令,查询出ORACLE_HOME 目录 3.然后进入$ORACLE_HOME/rdbms/a ...