BigDecimal为啥可以精确计算
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BigDecimal为啥可以精确计算相关的知识,希望对你有一定的参考价值。
参考技术A 计算机底层只能用二进制表示数,因此只能精确表示x*2^y类型的数,不能被此形式计算得来的数则只能通过多精度的方式近似地表示出来。BigDecimal能更精确表示带小数点的数值,因为采用了long intCompact和int scale来表示数值,
如果位数过大,不能用intCompact表示还会用BigInteger这个对象来表示大数字,本质是一个整形数组,而不是浮点型的科学计数法。
判断结果是否会溢出,不会就直接是long*long,溢出则会调用BigInteger的乘法
使用BigDecimal来进行精确计算
在一些以金融等行业中的计算是需要十分精确的,即使我们使用像double这样的类型,由于浮点数的原因,会使得数据计算变得不精确,例如下面的例子:
1 double a = 0.1; 2 double b = 0.005; 3 System.out.println(a+b);
则结果为:0.10500000000000001。
像double这样的浮点数类型,只能用于平常的科学计算,要想使得计算精确无误,必须使用Java中的BigDecimal类型。
例:
1 BigDecimal a = new BigDecimal("0.1"); 2 BigDecimal b = new BigDecimal("0.005"); 3 System.out.println(a.add(b).toString());
结果为:0.105。
注意,这里必须用字符串作为BigDecimal构造器的参数,这是因为如果直接使用double类型作为BigDecimal构造器的参数,则BigDecimal则将传入的使该double的二进制浮点值准确的十进制表示形式,这一点在其API手册上也明确表明了:
另外,即使是一个天文数字,BigDecimal也是可以计算的,这一点使用基本类型最大能表示的double也是无法做到的:
1 BigDecimal a = new BigDecimal("0.1489754523146487413157448756748784213458789485454213645874121548731248798"); 2 BigDecimal b = new BigDecimal("0.00548731452461421465478452364545123415451231256451"); 3 System.out.println(a.add(b).toString());
输出:0.1544627668392629559705293993203296555003912611099313645874121548731248798
例:
1 BigDecimal a = new BigDecimal("1"); 2 BigDecimal b = new BigDecimal("3"); 3 System.out.println(a.divide(b).toString());
这是一个错误的代码,会抛出异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
其实很简单,1除以3将会得到一个无限循环的小数,因此即使是BigDecimal也无法显示,当然divide方法还是有很多重载形式的,使用合适的重载方法就不会报错:
scale参数用于指定保留小数点的个数,roundingMode参数用于指定舍入模式:
1 BigDecimal a = new BigDecimal("1"); 2 BigDecimal b = new BigDecimal("3"); 3 System.out.println(a.divide(b, 3, BigDecimal.ROUND_DOWN));
结果:0.333。
以上是关于BigDecimal为啥可以精确计算的主要内容,如果未能解决你的问题,请参考以下文章