Gear with Code Java Engineer

BigInteger和BigDecimal类

2019-06-05

有些时候我们会遇到long和double提供的精度不够的情况(long大约为19位十进制有效数字,double大约为15~16位十进制有效数字),为了解决这个问题,java类库提供了BigInteger类和BigDecimal类。这两个类理论上能够表示任意精度的数字,并且提供计算方法,但是实际使用依赖于具体计算机的性能。

要明白精度和范围的概念是不同的。对于long来说,它的范围和精度是一致的,在它范围内的每个数字它都能够准确表示。然而对于double类型来说,熟系IEEE754标准的朋友知道,它的64位是由1个符号位,11个指数位,和52个尾数位来表示的,这52个尾数位就代表了它的精度。也就是说double的精度比long还要低一些。举个例子,像1234567890987654.123这个数小数点前面已经有16位了,虽然这个数在double的范围内,但是小数点后面这个.123是表示不出来的,也就是精度损失了。看下面一个例子:

public class k {
    public static void main(String args[]) {
        double d=1234567890987654.123;
        System.out.println(d);
    }
}

输出结果为:1.234567890987654E15 可以看出小数点后面的精度是损失了的,如果使用BigDecimal类再试试。

package jju;
import java.math.BigDecimal;
public class k {
    public static void main(String args[]) {
        BigDecimal bigD = new BigDecimal(1234567890987654.123);
        System.out.println(bigD);
    }
}

输出结果为:1234567890987654 为什么精度还是损失了呢,这是由于在构造BigDecimal的时候输入了1234567890987654.123,它默认是一个double类型,所以在传入之前就已经损失精度了。正确的做法是用String进行构造。

package jju;
import java.math.BigDecimal;
public class k {
    public static void main(String args[]) {
        BigDecimal bigD = new BigDecimal("1234567890987654.123");
        System.out.println(bigD);
    }
}

输出结果为:1234567890987654.123。与预期一致。

BigInteger的用法与BigDecimal类似。

需要注意的是这两个类是不可以使用+-*/等运算符的,需要使用类中的方法进行运算。此外,这两个类在计算效率方面要比基本类型低得多,所以如果不是必须的话,还是少用这两个类。


上一篇 java.lang.Math类

下一篇 表示日期的类

Comments

Content