Java中that.go_java之BigDecimal的加减乘除-Go语言中文社区

在小数之间加减乘除的时候,由于二进制不能精确表示小数,从而导致精度丢失。在实际开发中,这种情况是很糟糕的。为了解决这一情况,我们可以利用BgiDecimal。但是这中间还有些问题需要注意的。

1、加减乘

首先,我们来看一个实例

BigDecimal num1 = new BigDecimal(3.0);

BigDecimal num2 = new BigDecimal(2.1);

System.out.println(num1.add(num2));

打印结果

c313482fe959db4ac311f45bf529dd68.png

并不是我们期望的结果,从jdk参考手册,我们可以找到原因

The results of this constructor can be somewhat unpredictable. One might assume that writingnew 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 a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting thedouble to aString using the Double.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));

打印输出

aa82050e24b5c521dc498ac2e6386d22.png

这次是我们期望的结果。

所以,我创建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));打印输出

dcc5adb3490e44ebb9f26cb277817449.png

2.除

jdk提供了几种小数之间相除的方法。

BigDecimal num1 = new BigDecimal(3.0);

BigDecimal num2 = new BigDecimal(2.1);

System.out.println("divide->"+num1.divide(num2));

直接运行,奇怪的发现出现异常了

962e9edaebbeac53c380f2b412b08a18.png

从异常信息可以知道,相除的结果不能够用二进制精确表示,所以需要使用另外一个方法

BigDecimal num1 = new BigDecimal(3.0);

BigDecimal num2 = new BigDecimal(2.1);

System.out.println("divide->"+num1.divide(num2,3,RoundingMode.FLOOR));

57c1e400ba72777ef4e9f647e6e2bdb4.png

第二个参数表示,当结果是无限小数时,保留几位有效数字

第三个参数表示,如何保留有效数字,例如四舍五入、向下取等

var _hmt = _hmt || [];

(function() {

var hm = document.createElement("script");

hm.src = "https://hm.baidu.com/hm.js?5e96c091ce7bc89fd43194bbc14eaadc";

var s = document.getElementsByTagName("script")[0];

s.parentNode.insertBefore(hm, s);

})();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值