BigDecimal丢失精度的坑

问题:new BigDecimal(double d)的数值居然还是不精确的

double d = 0.09;
BigDecimal bigDecimal=new BigDecimal(d);
System.out.println(bigDecimal);
System.out.println(d);

输出结果:

0.0899999999999999966693309261245303787291049957275390625

0.09

 

原因:BigDecimal将double数据转换成为long bits,进行移位计算数值,而double的long bits移位计算是无法得到0.09的精确数值,所有造成数据精度丢失。

为了避免丢失double的数据精度,将double数据转成String,使用BigDecimal(String s)构造方法。

public class  BigDecimal extends Number implements Comparable<BigDecimal>{public BigDecimal(double val) {this(val,MathContext.UNLIMITED);}public BigDecimal(double val, MathContext mc) {if (Double.isInfinite(val) || Double.isNaN(val))throw new NumberFormatException("Infinite or NaN");// Translate the double into sign, exponent and significand, according// to the formulae in JLS, Section 20.10.22.long valBits = Double.doubleToLongBits(val);int sign = ((valBits >> 63) == 0 ? 1 : -1);int exponent = (int) ((valBits >> 52) & 0x7ffL);long significand = (exponent == 0? (valBits & ((1L << 52) - 1)) << 1: (valBits & ((1L << 52) - 1)) | (1L << 52));exponent -= 1075;// At this point, val == sign * significand * 2**exponent./** Special case zero to supress nonterminating normalization and bogus* scale calculation.*/if (significand == 0) {this.intVal = BigInteger.ZERO;this.scale = 0;this.intCompact = 0;this.precision = 1;return;}// Normalizewhile ((significand & 1) == 0) { // i.e., significand is evensignificand >>= 1;exponent++;}int scale = 0;// Calculate intVal and scaleBigInteger intVal;long compactVal = sign * significand;if (exponent == 0) {intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null;} else {if (exponent < 0) {intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal);scale = -exponent;} else { //  (exponent > 0)intVal = BigInteger.valueOf(2).pow(exponent).multiply(compactVal);}compactVal = compactValFor(intVal);}int prec = 0;int mcp = mc.precision;if (mcp > 0) { // do roundingint mode = mc.roundingMode.oldMode;int drop;if (compactVal == INFLATED) {prec = bigDigitLength(intVal);drop = prec - mcp;while (drop > 0) {scale = checkScaleNonZero((long) scale - drop);intVal = divideAndRoundByTenPow(intVal, drop, mode);compactVal = compactValFor(intVal);if (compactVal != INFLATED) {break;}prec = bigDigitLength(intVal);drop = prec - mcp;}}if (compactVal != INFLATED) {prec = longDigitLength(compactVal);drop = prec - mcp;while (drop > 0) {scale = checkScaleNonZero((long) scale - drop);compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);prec = longDigitLength(compactVal);drop = prec - mcp;}intVal = null;}}this.intVal = intVal;this.intCompact = compactVal;this.scale = scale;this.precision = prec;}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译型语言VS解释型语言

编译型语言人类代码 ————》一次性把代码给 翻译官&#xff08;编译器&#xff09;————》汇编--》机器语言代表 &#xff1a; c,c,golang优点&#xff1a;执行速度快缺点&#xff1a;跨平台可移植性差硬件 &#xff0c; cpu , 有自己指令规则 0000000001 打印&#xf…

P1236-Network of Schools(学校网络)【最强联通块,Kosaraju】

正题 POJ题目链接 给出一个图&#xff0c;求联通块数量和加入多少条边后会将全图变为一个最强联通块。 机翻输入输出&#xff08;需要自取&#xff09; 输入 第一行包含整数N&#xff1a;网络中的学校数量&#xff08;2 < N < 100&#xff09;。学校由前N个正整数标识…

限时团购,6.9折:《微信开发深度解析:公众号、小程序高效开发秘籍》推荐序

全书由目 Senparc.Weixin SDK 作者苏震巍历时 2 年完成&#xff0c;涵盖了开发微信公众号及小程序需要用的的各项后端开发技能、技巧、避坑提示&#xff0c;以及 Senparc.Weixin SDK 微信公众号及小程序模块全面的使用说明及原理剖析。 Senparc.Weixin SDK 发布 4 年多来&#…

SSM框架知识点复习

第三节 SSM框架知识点复习 SpringMVC的知识 技能:使用SpringMVC来处理浏览器发起的请求。 ① SpringMVC的基本使用流程 i. 导入jar包 ii. 配置SpringMVC的配置文件 iii. 配置web.xml文件 iv. 创建控制器类并声明单元方法 ② SpringMVC的单元方法获取请求 i. 使用形参名和键名一…

某同学工作之后的感悟

本文原创&#xff1a;王梦茹以下是王梦茹同学在学习中和工作中的感悟。01学习中出来之后发现在学校的学习效率是远远比自主学习效率高的&#xff0c;学什么东西之前都会先知道他的大体概念&#xff0c;通透了解一下再学习会发现有效率的多。在有大致了解的情况下再去听老师讲课…

“半路出家”的程序猿怎么不被“熊”

文本原创&#xff1a;孙浩投稿这篇文章总有点‘好为人师’的感觉&#xff0c;但是自己作为一个“半路出家”的程序看过太多的和我同样出身的程序半途而废了。我现在在一家软件公司就职&#xff0c;担任技术主管职位。01 带过毕业生&#xff0c;也带过中途转行&#xff0c;也带过…

这可能是把Docker的概念讲的最清楚的一篇文章

转载自 这可能是把Docker的概念讲的最清楚的一篇文章 Docker 是世界领先的软件容器平台&#xff0c;本文主要来介绍下关于Docker的那些事儿&#xff0c;主要包含以下内容&#xff1a; 容器 什么是Docker&#xff1f; Docker思想、特点 Docker容器主要解决什么问题 容器 V…

【2018.3.17】模拟赛之一-ssl2574jzoj1368 无限序列【斐波那契数列】

正题 链接 需要纪中OJ账号 刚开始一个字符串”1”。然后进行无数次变化&#xff0c;1变为10,0变为1。然后求多个区间内的1的个数 输入输出&#xff08;需要自取&#xff09; Input   第一行为一个整数Q&#xff0c;后面有Q行&#xff0c;每行两个数用空格隔开的整数a, b。 …

Python变量名的定义规则与定义方式

变量名的定义规则 1.变量名只能是 字母、数字或者下划线的任意组合 2.变量名的第一个字符不能是数字 3.一下关键字不能声明为变量名 常用定义方式 驼峰法 AgeOfOld56 NumberOfStudents22 下划线 age_of_old56 第二种为官方推荐 定义变量不好的方式举例 1.变量名为中…

洋葱架构简介——分离是为了更好的结合

写出高质量软件是困难和复杂的&#xff1a;不仅仅是为了满足需求&#xff0c;还应该是健壮的&#xff0c;可维护的&#xff0c;可测试的&#xff0c;并且足够灵活以适应成长和变化。这就是洋葱架构出现的原因&#xff0c;它代表一组优秀的开发实践&#xff0c;用来开发任何的软…

RBAC(基于角色的权限访问控制)

第一节.RBAC简介 英文全称(Role-Based Access Control)中文全称:基于角色的权限访问控制rbac: 一种数据库设计思想,根据设计数据库设计方案,完成项目的权限控制.经常需要添加权限的情景 4.1 不同用户登录后看到的菜单是不一样的. 4.2 不同用户看到的页面效果不一样 4.2.1 有的…

子列表只是原列表的一个视图

原文参考&#xff1a;《编写高质量代码&#xff1a;改善java程序的151个建议》本文原创&#xff1a;穆雄雄上期文章&#xff1a;subList?? subString???上期我们说到&#xff0c;List接口提供了subList方法&#xff0c;其作用是返回一个列表的子列表。并且我们通过案例说明…

python注释的用法(单and多行)

单行注释 # name"asdfdasfdas"多行注释 """ print(xy) aad2"""快捷键 先选中要注释的内容然后Ctrl/

【2018.3.17】模拟赛之二-ssl1862jzoj1366 删数【区间dp】

正题 链接 需要纪中OJ账号 有n个数&#xff0c;可以选择删除一段区间&#xff0c;价值为|xi – xk|*(k-i1)。求删完所有数的最大价值 输入输出&#xff08;需要自取&#xff09; Input    输入文件的第一行为一个正整数N&#xff0c;第二行有N个用空格隔开的N个不同的正整…

ASP.NET Core之跨平台的实时性能监控

前言 前面我们聊了一下一个应用程序 应该监控的8个关键位置. 应用程序的8个关键性能指标以及测量方法 最后卖了个小关子,是关于如何监控ASP.NET Core的. 今天我们就来讲讲如何监控它,下面上效果图: 阅读本文需要了解的相关技术与内容: InfluxDb(分布式时序数据库,开源)(注…

EasyUI(前端框架)

第一节 EasyUI的介绍和常用组件 [1]EasyUI的介绍 介绍: EasyUI是一个前端开发的框架&#xff0c;其将常用的页面开发使用的组件进行了 封装&#xff0c;前端开发人员只需将EasyUI的资源导入项目后使用即可&#xff0c;快速 提升开发效率。 使用&#xff1a; ① 导入EasyUI的资…

如何快速开发一个 Dubbo 应用

转载自 如何快速开发一个 Dubbo 应用 导读&#xff1a;在分布式系统中&#xff0c;远程调用是最基础也是最重要的基石。历史上&#xff0c;曾经先后出现过 CORBA、RMI、EJB、WebService 等技术和规范&#xff0c;在服务化以及微服务日趋流行的今天&#xff0c;更多的被广泛使…

‘小会计’的转行之旅

本文原创&#xff1a;王哈哈1大学学习的专业是会计学&#xff0c;目前社会上来说很普遍的工作&#xff0c;都说会计是越老越吃香&#xff0c;所以一毕业就先找了一份和专业相关的工作&#xff0c;然后就开始了抱着公司的大腿努力工作。毕业三年期间也换了几份工作&#xff0c;本…

【2018.3.17】模拟赛之三-ssl1863jzoj1367 俄罗斯方块【模拟】

正题 链接 需要纪中OJ账号 有7种方块 有n列&#xff0c;给出每列的方块高度&#xff0c;求一种方块所有方面都落地的方案数 输入输出&#xff08;需要自取&#xff09; Input 第一行为二个整数C和P&#xff0c;1 ≤ C ≤ 100, 1 ≤ P ≤ 7&#xff0c;表示列数和下落方…

Python缩进的几个原则

Python的缩进有以下几个原则 顶级代码必须顶行写&#xff0c;即如果一行代码本身不依赖于任何条件&#xff0c;那它必须不能进行任何缩进 同一级别的代码&#xff0c;缩进必须一致 官方建议缩进用4个空格