在小数之间加减乘除的时候,由于二进制不能精确表示小数,从而导致精度丢失。在实际开发中,这种情况是很糟糕的。为了解决这一情况,我们可以利用BgiDecimal。但是这中间还有些问题需要注意的。
1、加减乘 首先,我们来看一个实例
BigDecimal num1 = new BigDecimal(3.0);
BigDecimal num2 = new BigDecimal(2.1);
System.out.println(num1.add(num2));
打印结果
文章图片
并不是我们期望的结果,从jdk参考手册,我们可以找到原因
- The results of this constructor can be somewhat unpredictable. One might assume that writing
new BigDecimal(0.1)
in Java creates aBigDecimal
which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as adouble
(or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passedin to the constructor is not exactly equal to 0.1, appearances notwithstanding. - The
String
constructor, on the other hand, is perfectly predictable: writingnew BigDecimal("0.1")
creates aBigDecimal
which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that theString constructor be used in preference to this one. - When a
double
must be used as a source for aBigDecimal
, note that this constructor provides an exact conversion; it does not give the same result as converting thedouble
to aString
using theDouble.toString(double)
method and then using theBigDecimal(String)
constructor. To get that result, use thestatic
valueOf(double)
method.
我们再来看另外一个例子
BigDecimal num1 = BigDecimal.valueOf(3.0);
BigDecimal num2 = BigDecimal.valueOf(2.1);
System.out.println(num1.add(num2));
打印输出
文章图片
这次是我们期望的结果。 所以,我创建BigDecimal对象的时候,最好通过静态方法valueOf(double)
当然,我们也可以通过另外一种方式。先将double值转为字符串,再通过Bigdecimal的构造函数创建对象
BigDecimal num1 = new BigDecimal(Double.toString(3.0));
//或者3.0 + ""
BigDecimal num2 = new BigDecimal(Double.toString(2.1));
//或者2.1 + ""
System.out.println("add->"+num1.add(num2));
System.out.println("subtract->"+num1.subtract(num2));
System.out.println("multiply->"+num1.multiply(num2));
打印输出
文章图片
2.除 jdk提供了几种小数之间相除的方法。
BigDecimal num1 = new BigDecimal(3.0);
BigDecimal num2 = new BigDecimal(2.1);
System.out.println("divide->"+num1.divide(num2));
直接运行,奇怪的发现出现异常了
文章图片
从异常信息可以知道,相除的结果不能够用二进制精确表示,所以需要使用另外一个方法
BigDecimal num1 = new BigDecimal(3.0); BigDecimal num2 = new BigDecimal(2.1); System.out.println("divide->"+ num1.divide(num2,3,RoundingMode.FLOOR));
文章图片
第二个参数表示,当结果是无限小数时,保留几位有效数字 第三个参数表示,如何保留有效数字,例如四舍五入、向下取等 【java之BigDecimal的加减乘除】
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)