Java BigDecimal和double

BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。从这个表示方法来看,BigDecimal只能标识有限小数,不过可以表示的数据范围远远大于double,在实际应用中基本足够了。

下面提一下两个精度问题:
问题一:BigDecimal的精度问题(StackOverflow上有个家伙问了相关的问题)
System.out.println(new BigDecimal(0.1).toString()); // 0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal("0.1").toString()); // 0.1
System.out.println(new BigDecimal(
Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());// 0.1
System.out.println(new BigDecimal(Double.toString(0.1)).toString()); // 0.1

分析一下上面代码的问题(注释的内容表示此语句的输出)

第一行:事实上,由于二进制无法精确地表示十进制小数0.1,但是编译器读到字符串"0.1"之后,必须把它转成8个字节的double值,因此,编译器只能用一个最接近的值来代替0.1了,即0.1000000000000000055511151231257827021181583404541015625。因此,在运行时,传给BigDecimal构造函数的真正的数值是0.1000000000000000055511151231257827021181583404541015625。
第二行:BigDecimal能够正确地把字符串转化成真正精确的浮点数。
第三行:问题在于Double.toString会使用一定的精度来四舍五入double,然后再输出。会。Double.toString(0.1000000000000000055511151231257827021181583404541015625)输出的事实上是"0.1",因此生成的BigDecimal表示的数也是0.1。
第四行:基于前面的分析,事实上这一行代码等价于第三行
结论:
1.如果你希望BigDecimal能够精确地表示你希望的数值,那么一定要使用字符串来表示小数,并传递给BigDecimal的构造函数。
2.如果你使用Double.toString来把double转化字符串,然后调用BigDecimal(String),这个也是不靠谱的,它不一定按你的想法工作。
3.如果你不是很在乎是否完全精确地表示,并且使用了BigDecimal(double),那么要注意double本身的特例,double的规范本身定义了几个特殊的double值(Infinite,-Infinite,NaN),不要把这些值传给BigDecimal,否则会抛出异常。
问题二:把double强制转化成int,难道不是扔掉小数部分吗?
int x=(int)1023.99999999999999; // x=1024为什么?

原因还是在于二进制无法精确地表示某些十进制小数,因此1023.99999999999999在编译之后的double值变成了1024。

所以,把double强制转化成int确实是扔掉小数部分,但是你写在代码中的值,并不一定是编译器生成的真正的double值。
验证代码:
double d = 1023.99999999999999;
int x = (int) d;
System.out.println(new BigDecimal(d).toString()); // 1024
System.out.println(Long.toHexString(Double.doubleToRawLongBits(d))); // 4090000000000000
System.out.println(x); // 1024

前面提过BigDecimal可以精确地把double表示出来还记得吧。

我们也可以直接打印出d的二进制形式,根据IEEE 754的规定,我们可以算出0x4090000000000000=(1024)。

转载于:https://www.cnblogs.com/yelongsan/p/4120913.html

java bigDecimal and double相关推荐

  1. Java BigDecimal和double区别

    转自:  https://www.cnblogs.com/mingforyou/p/3344489.html BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或doubl ...

  2. Java BigDecimal类的一般使用、BigDecimal转double

    BigDecimal大据类. 浮点型运算的时候直接 加减乘除时可能会出现数据失真(精度问题). BigDecimal可以解决浮点型运算数据失真的问题. double a = 0.1;double b ...

  3. java总结:double取两位小数的多种方法

    1.方法一四舍五入:import java.math.BigDecimal;double f = 111231.5585; BigDecimal b = new BigDecimal(f); doub ...

  4. java bigdecimal赋值_Java中BigDecimal类介绍及用法(亲测)

    Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteger 类是 ...

  5. Java BigDecimal初探

    更新时间:2016-03-17 一.引言 <Effactive Java>中有这样的描述:float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为 ...

  6. Java:对double值进行四舍五入,保留两位小数的几种方法

    转载自   Java:对double值进行四舍五入,保留两位小数的几种方法 1. 功能 将程序中的double值精确到小数点后两位.可以四舍五入,也可以直接截断. 比如:输入12345.6789,输出 ...

  7. Java BigDecimal valueOf()方法与示例

    BigDecimal类的valueOf()方法 (BigDecimal Class valueOf() method) Syntax: 句法: public static BigDecimal val ...

  8. Java BigDecimal 转换,除法陷阱(转)

    源地址:   http://blog.csdn.net/niannian_315/article/details/24354251 今天在用BigDecimal"出现费解"现象,以 ...

  9. Java学习之double类型数据比较

    Java学习之double类型数据比较 对于两个double类型的数据,是不能直接用==来比较是否相等 double a=1.01; double b=1.01; if(b==a){System.ou ...

最新文章

  1. DPDK — TestPMD
  2. ajax请求php保存数据格式,jQuery ajax与php进行数据交互(数据格式问题)
  3. 服务部署如何做到高可用?这份“三级跳”秘籍送给你
  4. 设置textview背景色为透明
  5. 所请求vi未加载至服务器内存_linux下tomcat端口请求数太大,导致服务器资源加载过慢的配置优化...
  6. java 本季度_Java获取当天、本周、本月、本季度、本年等 开始及结束时间
  7. boot sprint 项目结构_完美起航-【知识】SpringBoot项目结构目录
  8. EXCEL 分列功能的使用
  9. excel 汉字转拼音
  10. 驱动开发:实现驱动加载卸载工具
  11. 手机照片分辨率dpi怎么调?一寸证件照照片dpi怎么调300?
  12. Siebel命令行修改LDAP
  13. coldfusion php,PHP加密代码转换为ColdFusion
  14. 热设计功耗(TDP)与功耗(P)
  15. 计算机开机时前按什么键,开机怎么进入bios?电脑开机按什么键进入BIOS方法大全...
  16. 安卓应用 - 公开市场上传投放
  17. matlab矩阵按位取反,第二章matlab的理基本使用方法.ppt
  18. WSTMart 国内开源商城系统佼佼者
  19. 僵木蠕病毒快速处置建议(零成本)
  20. Blueprint介绍和使用

热门文章

  1. jQuery以JSONP的访问调用一个WCF REST服务
  2. C#中字符串保留双引号
  3. unity3d 人员控制代码
  4. 洛谷P1828 香甜的黄油 Sweet Butter
  5. 社交大佬们的数据“大”在哪里?
  6. 企业如何寻找最合适的托管数据中心,以维持IT和业务的增长运营
  7. Docker监控方案(TIG)的研究与实践之Influxdb
  8. paper 35 :交叉验证(CrossValidation)方法思想
  9. vmware安装minimal centos报错/etc/rc5.d/s99local : line
  10. Xamarin开发IOS笔记:切换输入法时输入框被遮住