Java大数字类型(BigInteger类和BigDecimal类)
在学习BigInteger类和BigDecimal类之前先回顾一下java中的基本数据类型
四类八种数据类型:
数据类型 | 关键字 | 内存占用 | 取值范围 | 包装类 |
---|---|---|---|---|
整数 | byte | 1 | 负的2的7次方 ~ 2的7次方-1(-128~127) | Byte |
short | 2 | 负的2的15次方 ~ 2的15次方-1(-32768~32767) | Short | |
int | 4 | 负的2的31次方 ~ 2的31次方-1 | Integer | |
long | 8 | 负的2的63次方 ~ 2的63次方-1 | Long | |
浮点数 | float | 4 | 1.401298e-45 ~ 3.402823e+38 | Float |
double | 8 | 4.9000000e-324 ~ 1.797693e+308 | Double | |
字符 | char | 2 | 0-65535 | Character |
布尔 | boolean | 1 | true,false | Boolean |
java的基本数据类型中能存储整型最大数值为long类型的最大取值:2^63-1,而如果想要存储一个更大的整型基本上数据类型是无法实现的,为解决这个问题,Java中提供啦包装类:BigInteger(可以认为是无穷大);而在使用浮点类型时,由于计算机底层存储为2进制数据会造成数据精度丢失问题,所以Java提供了包装类:BigDecimal
BigInteger类
BigInteger所在包是在java.math包下,因此在使用的时候就需要进行导包。我们可以使用BigInteger类进行大整数的计算
常见方法
构造方法
public BigInteger(int num, Random rnd) //获取随机大整数,范围:[0 ~ 2的num次方-1] public BigInteger(String val) //获取指定的大整数 public BigInteger(String val, int radix) //获取指定进制的大整数 下面这个不是构造,而是一个静态方法获取BigInteger对象 public static BigInteger valueOf(long val) //静态方法获取BigInteger的对象,内部有优化 细节:对象一旦创建里面的数据不能发生改变。
示例代码:
//1.获取一个随机的大整数
Random r=new Random();
for (int i = e; i < 100; i++) {
BigInteger bd1 = new BigInteger(4,r);
System.out.println(bd1);//[@ ~ 15]}
}
//2.获取一个指定的大整数,可以超出long的取值范围
//细节:字符串中必须是整数,否则会报错
BigInteger bd2 = new BigInteger("1.1");
System.out.println(bd2);
BigInteger bd3 = new BigInteger("abc");
System.out.println(bd3);
//3.获取指定进制的大整数
//细节:
//1.字符串中的数字必须是整数
//2.字符串中的数字必须要跟进制吻合。
//比如二进制中,那么只能写日和1,写其他的就报错。
BigInteger bd4 = new BigInteger("123", 2);
System.out.println(bd4);
//4.静态方法获取BigInteger的对象,内部有优化
//细节:
//1.能表示范围比较小,只能在long的取值范围之内,如果超出long的范围就不行了。
//2.在内部对常用的数字: -16 ~ 16 进行了优化。
// 提前把-16~16 先创建好BigInteger的对象,如果多次获取不会重新创建新的。
BigInteger bd5 = BigInteger.valueOf(16);
BigInteger bd6 = BigInteger.valueOf(16);
System.out.println(bd5 == bd6);//true
BigInteger bd7 = BigInteger.valueOf(17);
BigInteger bd8 = BigInteger.valueOf(17);
System.out.println(bd7 == bd8);//false
//5.对象一旦创建内部的数据不能发生改变
BigInteger bd9 =BigInteger.valueOf(1);
BigInteger bd10 =BigInteger.valueOf(2);
//此时,不会修改参与计算的BigInteger对象中的借,而是产生了一个新的BigInteger对象记录
BigInteger result=bd9.add(bd10);
System.out.println(result);//3
构造方法小结:
- 如果BigInteger表示的数字没有超出long的范围,可以用静态方法获取。
- 如果BigInteger表示的超出long的范围,可以用构造方法获取。
- 对象一旦创建,BigInteger内部记录的值不能发生改变。
- 只要进行计算都会产生一个新的BigInteger对象
常见成员方法
BigDecimal类中使用最多的还是提供的进行四则运算的方法,如下:
public BigInteger add(BigInteger val) //加法 public BigInteger subtract(BigInteger val) //减法 public BigInteger multiply(BigInteger val) //乘法 public BigInteger divide(BigInteger val) //除法 public BigInteger[] divideAndRemainder(BigInteger val) //除法,获取商和余数 public boolean equals(Object x) //比较是否相同 public BigInteger pow(int exponent) //次幂、次方 public BigInteger max/min(BigInteger val) //返回较大值/较小值 public int intValue(BigInteger val) //转为int类型整数,超出范围数据有误
示例代码:
//1.创建两个BigInteger对象
BigInteger bd1 = BigInteger.valueOf(10);
BigInteger bd2 = BigInteger.valueOf(5);
//2.加法
BigInteger bd3 = bd1.add(bd2);
System.out.println(bd3);
//3.除法,获取商和余数
BigInteger[] arr = bd1.divideAndRemainder(bd2);
System.out.println(arr[0]);
System.out.println(arr[1]);
//4.比较是否相同
boolean result = bd1.equals(bd2);
System.out.println(result);
//5.次幂
BigInteger bd4 = bd1.pow(2);
System.out.println(bd4);
//6.max
BigInteger bd5 = bd1.max(bd2);
//7.转为int类型整数,超出范围数据有误
BigInteger bd6 = BigInteger.valueOf(2147483647L);
int i = bd6.intValue();
System.out.println(i);
BigInteger bd6 = BigInteger.valueOf(200);
double v = bd6.doubleValue();
System.out.println(v);//200.0
底层存储方式:
因为计算机存储数据都是0101010101,数据类型是编程语言自己规定的,所以在实际存储的时候,先把具体的数字变成二进制,每32个bit为一组,存储在数组中。 数组中最多能存储元素个数:21亿多数组中每一位能表示的数字:42亿多。理论上,BigInteger能表示的最大数字为:42亿的21亿次方。
但是还没到这个数字,电脑的内存就会撑爆,所以一般认为BigInteger是无限的。
BigDecimal类
在使用float或者double类型的数据在进行数学运算的时候,很有可能会产生精度丢失问题。我们都知道计算机底层在进行运算的时候,使用的都是二进制数据; 当我们在程序中写了一个十进制数据 ,在
进行运算的时候,计算机会将这个十进制数据转换成二进制数据,然后再进行运算,计算完毕以后计算机会把运算的结果再转换成十进制数据给我们展示; 如果我们使用的是整数类型的数据进行计算,那
么在把十进制数据转换成二进制数据的时候不会存在精度问题; 如果我们的数据是一个浮点类型的数据,有的时候计算机并不会将这个数据完全转换成一个二进制数据,而是将这个将其转换成一个无限的
趋近于这个十进数的二进制数据; 这样使用一个不太准确的数据进行运算的时候, 最终就会造成精度丢失;为了提高精度,Java就给我们提供了BigDecimal供我们进行数据运算。
常见方法
- 在使用float或者double类型的数据在进行数学运算的时候,有可能会产生精度丢失问题
构造方法
BigDecimal(int val) BigDecimal(long val) BigDecimal(String val)
常见成员方法
BigDecimal类中使用最多的还是提供的进行四则运算的方法,如下:
public BigDecimal add(BigDecimal value) // 加法运算 public BigDecimal subtract(BigDecimal value) // 减法运算 public BigDecimal multiply(BigDecimal value) // 乘法运算 public BigDecimal divide(BigDecimal value) // 触发运算
实例代码:
// 创建两个BigDecimal对象
BigDecimal b1 = new BigDecimal("0.3") ;
BigDecimal b2 = new BigDecimal("4") ;
System.out.println(b1.add(b2)); // 进行加法运算
System.out.println(b1.subtract(b2)); // 进行减法运算
System.out.println(b1.multiply(b2)); // 进行乘法运算
System.out.println(b1.divide(b2)); // 进行除法运算
注意点: 结果是一个无限循环小数,那么就会报错:ArithmeticException(使用divide
解决)
底层存储方式:
把数据看成字符串,遍历得到里面的每一个字符,把这些字符在ASCII码表上的值,都存储到数组中。