文章目录
- BigInteger
- BigInteger构造方法
- 小结
- BigInteger常见成员方法
- BigInteger底层存储方式
- BigDecimal
- 计算机中的小数
- BigDecimal的作用
- BigDecimal的使用
- BigDecimal底层存储方式
- 总结
BigInteger
- 在Java中,整数有四种类型:byte,short,int,long
- 在底层占用字节个数:byte1字节,short2字节,int4字节,long8字节
long为例:
表示
如果超出这个范围,BigInteger还可以表示,有上限,但可以理解为无穷大
BigInteger构造方法
方法名 | 说明 |
public BigInteger(int num, Random rand) | 获取随机大整数,范围:[0~2的num次方-1] |
public BigInteger(String val) | 获得指定的大整数 |
public BigInteger(String val, int radix) | 获得指定进制的大整数 |
public static BigInteger valueOf(long val) | 静态方法获取BigInteger的对象,内部有优化 |
代码演示:
public class BigIntegerDemo1 {
public static void main(String[] args) {
//1。获取一个随机大整数
BigInteger bd1 = new BigInteger(4, new Random());
//[0 , 2^4-1=15]
System.out.println(bd1);
//2。获取一个指定的大整数
//细节:字符串中必须是整数,否则会报错
//99999999999999999999999999
BigInteger bd2 = new BigInteger("99999999999999999999999999");
System.out.println(bd2);
//3。获取一个指定进制的大整数
//细节:
// 字符串中的数字必须是整数
// 字符串中的数字必须要跟进制吻合,比如二进制中只能写0和1,写其他会报错
BigInteger bd3 = new BigInteger("100", 10);
//100
System.out.println(bd3);
BigInteger bd4 = new BigInteger("100", 2);
//4
System.out.println(bd4);
//4。静态方法获取BigInteger的对象,内部有优化
//细节:
// 能表示的范围比较小,在long的取值范围内,超过long范围就不行了。
// 在内部对常用的数字:-16 ~ 16 进行了优化
// 提前把-16 ~ 16 先创建好BigInteger的对象,如果多次获取不会重新创建新的。
BigInteger bd5 = BigInteger.valueOf(100);
//100
System.out.println(bd5);
//9223372036854775807
System.out.println(Long.MAX_VALUE);
//报错--过大的整数
//BigInteger bd6 = BigInteger.valueOf(9223372036854775808L);
//System.out.println(bd6);
BigInteger bd7 = BigInteger.valueOf(16);
BigInteger bd8 = BigInteger.valueOf(16);
//true
System.out.println(bd7 == bd8);
BigInteger bd9 = BigInteger.valueOf(17);
BigInteger bd10 = BigInteger.valueOf(17);
//false
System.out.println(bd9 == bd10);
}
}
小结
- 如果BigInteger表示的数字没有超出
long
的范围,用静态方法获取
public static BigInteger valueOf(long val)
- 如果BigInteger表示的超出
long
的范围或者不确定的情况,用构造方法获取
public BigInteger(String val)
- 对象一旦创建,内部记录的值不能发生改变
- 只要进行计算都会产生一个新的BigInteger对象
BigInteger常见成员方法
方法名 | 说明 |
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类型整数,超出范围数据有误 |
public int longValue(BigInteger val) | 转为long类型整数,超出范围数据有误 |
public int doubleValue(BigInteger val) | 转为int类型整数,超出范围数据有误 |
代码演示:
import java.math.BigInteger;
public class BigIntegerDemo2 {
public static void main(String[] args) {
//1。创建两个BigInteger对象
BigInteger bd1 = BigInteger.valueOf(10);
BigInteger bd2 = BigInteger.valueOf(3);
//2。加减乘除
BigInteger bd3 = bd1.add(bd2);
//13
System.out.println(bd3);
//3。除法,获取商和余数
BigInteger[] arr = bd1.divideAndRemainder(bd2);
//2
System.out.println(arr.length);
//3
System.out.println(arr[0]);
//1
System.out.println(arr[1]);
//4。比较是否相同
//false
System.out.println(bd1.equals(bd2));
BigInteger bd4 = BigInteger.valueOf(3);
//true
System.out.println(bd2.equals(bd4));
//5。次幂
//100
System.out.println(bd1.pow(2));
//6。返回较大值/较小值
BigInteger bd5 = bd1.max(bd2);
//10
System.out.println(bd5);
//true
//说明不会创建新的BigInteger对象
System.out.println(bd5 == bd1);
//false
System.out.println(bd5 == bd2);
//7。转为int类型整数,超出范围数据有误
BigInteger bd6 = BigInteger.valueOf(1000);
int i = bd6.intValue();
//1000
System.out.println(i);
BigInteger bd7 = BigInteger.valueOf(2147483658L);
//-2147483638
System.out.println(bd7.intValue());
//1000
System.out.println(bd6.longValue());
//1000.0
System.out.println(bd6.doubleValue());
}
}
BigInteger底层存储方式
- 对计算机而言,其实是没有数据类型的概念的,都是0101010101010。
- 数据类型是编程语言自己规定的。
- 第一位记录的是数字的正负,1–>正数 -1->负数
- 将数字变成补码形式,32位为一组,分成n组,再转成十进制存储在数组中。
- 数组的最大长度是int的最大值:
2147483647
- 数组中每一位能表示的数字:
-2147483648 ~ 2147483647
- 数组中最多能存储元素个数:21亿多
- 数组中每一位能表示的数字:42亿多
- BigInteger能表示的最大数字为:42亿的21亿次方
BigDecimal
public class BigDecimalDemo1 {
public static void main(String[] args) {
//0.09999999999999999
System.out.println(0.09 + 0.01);
//0.11599999999999999
System.out.println(0.216 - 0.1);
//0.0022600000000000003
System.out.println(0.226 * 0.01);
//0.8999999999999999
System.out.println(0.09 / 0.1);
}
}
计算机中的小数
十进制的小树在计算机的存储如下
- 小数部分
如果要将十进制的小树转成二进制,可能会有很长很长,而在java中,float和double所占的字节数有限,超出的部分只能舍弃 --> 不精确 --> 后续计算也会不精确
但有些情况是需要必须精确的,比如贷款买房子,或飞机火箭等精密零件上的计算必须精确
BigDecimal的作用
- 用于小数的精确计算,解决小数运算失真问题。
- 用来表示很大的小数
import java.math.BigDecimal;
public class BigDecimalDemo2 {
public static void main(String[] args) {
//1.通过传递double类型的小数来创建对象
//细节:这种方式有可能是不精确的,所以不建议使用
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal(0.09);
//0.01000000000000000020816681711721685132943093776702880859375
System.out.println(bd1);
//0.0899999999999999966693309261245303787291049957275390625
System.out.println(bd2);
//2.通过传递字符串表示的小数来创建对象
BigDecimal bd3 = new BigDecimal("0.01");
BigDecimal bd4 = new BigDecimal("0.09");
//0.01
System.out.println(bd3);
//0.09
System.out.println(bd4);
//0.10
System.out.println(bd3.add(bd4));
//3.通过静态方法获取对象
//10
System.out.println(BigDecimal.valueOf(10));
}
}
细节:
- 1.如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
- 2.如果要表示的数字比较大,超出double的取值范围,建议使用构造方法
- 3.如果我们传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新new
BigDecimal bd6 = BigDecimal.valueOf(10);
BigDecimal bd7 = BigDecimal.valueOf(10);
//true
System.out.println(bd6 == bd7);
BigDecimal bd8 = BigDecimal.valueOf(10.0);
BigDecimal bd9 = BigDecimal.valueOf(10.0);
//BigDecimal.valueOf()中必须是整数
//false
System.out.println(bd8 == bd9);
BigDecimal的使用
方法名 | 说明 |
public static BigDecimal valueOf (double val) | 获取对象 |
public BigDecimal add(BigDecimal val) | 加法 |
public BigDecimal subtract(BigDecimal val) | 减法 |
public BigDecimal multiply(BigDecimal val) | 乘法 |
public BigDecimal divide(BigDecimal val) | 除法 |
public BigDecimal divide(BigDecimal val,精确几位,舍入模式) | 除法 |
代码演示:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalDemo3 {
public static void main(String[] args) {
//1.加法
BigDecimal bd1 = BigDecimal.valueOf(10.0);
BigDecimal bd2 = BigDecimal.valueOf(2.0);
BigDecimal bd3 = bd1.add(bd2);
//12.0
System.out.println(bd3);
//2.减法
//8.0
System.out.println(bd1.subtract(bd2));
//3.乘法
//20.00
System.out.println(bd1.multiply(bd2));
//4.除法
//5
System.out.println(bd1.divide(bd2));
//如果是10/3除不尽的情况,系统就会报错只能用下面的方法
BigDecimal bd4 = BigDecimal.valueOf(3.0);
//保留两位小数
//ROUND_HALF_UP 四舍五入模式
//3.33
//System.out.println(bd1.divide(bd4, 2,BigDecimal.ROUND_HALF_UP));
System.out.println(bd1.divide(bd4, 2, RoundingMode.HALF_UP));
}
}
舍入模式:
-
UP
:远离零方向舍入的舍入模式 -
DOWN
:向零方向舍入的舍入模式 -
CEILING
:向无限大方向舍入的舍入模式 -
FLOOR
:向负无穷大方向舍入的舍入模式 -
HALF_UP
:四舍五入,0.5进1 -
HALF_DOWN
:四舍五入,0.5舍弃
BigDecimal底层存储方式
- 遍历得到每一个字符
- 把字符转换成ASCII表中的数值进行存储
- 负数也会把负号的ASCII表值存储
总结
- BigDecimal的作用是什么?
- 表示较大的小数和解决小数运算精度失真的问题。
- BigDecimal的对象如何获取?
BigDecimal bd1 = new BigDecimal("较大的数");
BigDecimal bd2 = BigDecimal.valueOf(0.1);
- 常见操作
- 加:
add
- 减:
subtract
- 乘:
multiply
- 除:
divide(四舍五入:RoundingMode.HALF_UP)