问题: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;}
}

BigDecimal丢失精度的坑相关推荐

  1. 面试:BigDecimal一定不会丢失精度吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源 | urlify.cn/ZVN7Nb 我们基本已经形成了常识 ...

  2. 面试官:BigDecimal一定不会丢失精度吗?

    都知道Double会丢失精度,BigDecimal就不会么?希望你会正确使用! 我们基本已经形成了常识,需要用到金钱的地方要用 BigDecimal 而不是其他,而我们也都知道浮点型变量在进行计算的时 ...

  3. 面试官:BigDecimal 一定不会丢失精度吗?

    前言 我们都知道浮点型变量在进行计算的时候会出现丢失精度的问题.如下一段代码: System.out.println(0.05 + 0.01); System.out.println(1.0 - 0. ...

  4. Java中BigDecimal解决精度丢失问题

    1.我们先看一个例子 可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题.那么我们如果在进行商品价格计算的时候,就会出现问题.很有可能造成我们手中有0.06元,却无法购买一个0.05元和一 ...

  5. double类型数据做加和操作时会丢失精度问题处理

    double类型的数据做加和操作 时会丢失精度,如下操作结果为: int a = 3;         double b = 0.03;         double c = 0.03; double ...

  6. golang中的json decode丢失精度的问题

    最近发现的一个坑 当用enconding/json包的时候,数字默认是处理为float64类型的,这就导致了int64可能会丢失精度,这时候要用dec.UseNumber将处理的数字转换成json.N ...

  7. 不丢失精度的获取照片的Gps经纬度

    不丢失精度的获取照片的Gps经纬度 1. 实际照片存储经纬度 2. **用pyhton exifread读取** 3. 用java metadata-extractor读取 4. windows用 e ...

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

    Long类型转json时前端js丢失精度解决方案 参考文章: (1)Long类型转json时前端js丢失精度解决方案 (2)https://www.cnblogs.com/lvgg/p/7475140 ...

  9. js long类型精度丢失_浮点数丢失精度

    问题 浮点数在运算过程中常常会丢失精度,这是由于二进制数的存储特点造成的,在php或者js中进行浮点数运算或者类型转换的时候常常会丢失精度.而在电商公司,对金额比较敏感,是万万不能接受丝毫的误差的. ...

最新文章

  1. python3 image模块_python3之成像库pillow
  2. sendmessage和postmessage的区别
  3. xml vs db.properties
  4. MOON.ORM 3.5 MYSQL的配置及使用方法(最新版免费下载使用.欢迎加盟)
  5. java string 转 inputstream_String和inputstream互转【转文】
  6. LeetCode算法入门- Palindrome Number-day2
  7. Bailian3713 外星人翻译用数字转换模块【递归+映射】
  8. 本地安装的smushit,如何压缩图片
  9. VM两个虚拟机之间的通讯测试
  10. 读“让你的软件飞起来”持续更新代码运行效率之路
  11. java 八进制 转义字符_string中转义字符
  12. 营收与预测:线性回归建立预测收入水平的线性回归模型。
  13. android -------- ConstraintLayout 宽高比和偏移量比(三)
  14. 关于Python对于图像处理详解
  15. 解决力扣等国外网站打不开问题
  16. 笔记本计算机提升性能,如何加快笔记本电脑的运行速度?
  17. 提出现代计算机工作原理的科学家是谁,现代计算机之父是谁_计算机信息处理能力_计算机能自动工作原理(2)...
  18. 设置jsp打开的默认方式
  19. Python问题:NotImplementedError: The confidence keyword argument is only available if OpenCV is install
  20. Redis——Redis哨兵模式

热门文章

  1. 机器学习之琐碎知识(代码运行问题)
  2. 开头th_是什么文件_Python文件读写最详细的讲解
  3. vector容器中关于处理从非0位置开始赋值的操作
  4. Java但中获取时间将时间转换成字符串格式(年月日格式)
  5. C++实现井字棋小游戏(写得不好,留作纪念!!!)
  6. Cannot find or open the PDB file
  7. HDU 6061 RXD and functions(NTT)
  8. SP5971 LCMSUM - LCM Sum
  9. P4173 残缺的字符串 FFT匹配含有通配符的字符串
  10. 【TC10738】TheContest【Hall 定理】【贪心】【二分图匹配】