BigInteger,BigDecimal

BigInteger

方法名 说明
public BigInteger(int num, Random rnd) 获取随机大整数,范围:[0~2的num次方-1]
public BigInteger(String val) 获取指定的大整数
public BigInteger(String val,int radix) 获取指定进制的大整数

拓展:public static BigInter valueOf(long val) 静态方法获取BigInteger的对象,内部有优化

tips:对象一旦创建,内部记录的值不能发生改变

代码演示:

for (int i = 0; i < 10; i++) {
    BigInteger bi=new BigInteger(4,new Random());
    System.out.println(bi);
}

bi的取值范围i就是[0,15(2的4次方减1)]

public static BigInter valueOf(long val) 静态方法获取BigInteger的对象,内部有优化

接下来我们看一下上面这句是如何优化的,既然BigInteger(String val)也可以获取指定的大整数二者有上面不同呢

1.首先我们可以看到,第二种传的参是long类型的数据,如果超出long的范围就会报错

2.在内部对常用的数字:-16~16进行了优化,我们直接阅读源码

3.如果在-16~16直接的数字是不创建新对象的

public static BigInteger valueOf(long val) {
    // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
    if (val == 0)
        return ZERO;
    if (val > 0 && val <= MAX_CONSTANT)
        return posConst[(int) val];
    else if (val < 0 && val >= -MAX_CONSTANT)
        return negConst[(int) -val];

    return new BigInteger(val);
}
private static final int MAX_CONSTANT = 16;
public static final BigInteger ZERO = new BigInteger(new int[0], 0);

我把主要源码找到阅读,首先先把传的值进行判断,先看是不是等于0,如果等于0直接走return ZERO,ZERO,最后就是直接调用了BigInteger(new int[0], 0)方法,把0直接返回;如果在在(0,MAX_CONSTANT]走第一句,可以看到MAX_CONSTANT = 16;即(0,16],如果不属于这三个判断,就直接调用BigInteger(val)方法,等于直接获取大整数

验证第三点:

BigInteger bi1= BigInteger.valueOf(16);
BigInteger bi2= BigInteger.valueOf(16);
System.out.println(bi1==bi2);//true

BigInteger bi3= BigInteger.valueOf(17);
BigInteger bi4= BigInteger.valueOf(17);
System.out.println(bi3==bi4);//false

还有一些关于BigInteger的运算方法就不一一赘述和演示了,可查看API自行阅读

拓展:关于BigInteger底层的储存方式

采用了Debug的方式
可以看到他是先定义了一个数组

第一步先把你传的数转成二进制的补码,然后把你传进来的值进行分段,每32位就是一段,存入mag数组中,signum代表的就是符号位,1正数,-1就是负数

数组中最多能存储的元素个数:21亿多

数组中每一个元素能表示的数字:42亿多

BigInteger能表示的最大数字为:42亿多的21亿多次方,这个数据无法想象

BigDecimal

首先了解这个之前,我们知道小数在Java代码中计算不精确,但是为什么不精确呢

我们分析一下(进制中小数的转换不赘述)

比如

十进制0.875它的二进制是111

十进制0.9它的二进制是111001100110011001100110011001100,,(45位)

十进制0.226它的二进制是:55位

首先:float总bit位数是32个bit位,小数占23个bit位

​ double总bit位数是64个bit位,小数52个bit位

但是像0.225这种怎么办呢,只能舍弃最后三位,保留小数部分前52位

于是Java就推出了BigDecimal用于精确计算

但是我这里就不讲关于BigDecima的加减乘除等计算了,讲述一下某些字段的四舍五入模式

方法名 说明
public BigDecimal add(BigDecima val) 加法
public BigDecimal subtract(BigDecima val) 减法
public BigDecimal multiply(BigDecima val) 乘法
public BigDecimal dividend(BigDecima val,精确几位,舍入模式) 除法

UP:远离零方向的舍入模式 DOWN:向零方向舍入的舍入模式

输入数字 舍入后 输入数字 舍入后

5.5 6 5.5 5

5.1 6 5.1 5

-1.1 -2 -1.1 -1

-1.8 -2 -1.8 -1

CEILING:向正无限大方向舍入的舍入模式 FLOOR:向负无限大方向舍入的舍入模式

输入数字 舍入后 输入数字 舍入后

5.5 6 5.5 6

5.1 5 5.1 5

-1.1 -1 -1.1 -1

-1.8 -1 -1.8 -1

ROUND_HALF_DOWN:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为up舍入的舍入模式。则为向上舍入的舍入模式如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。

例如:4.8舍入后 5 4.2舍入后 4 4.5舍入后5

ROUND_HALF_UP:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。注意,这是我们大多数人在小学时就学过的舍入模式。

例如4.5舍入后5

ROUND_HALF_EVEN:向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

posted @ 2022-11-09 14:35  喜欢七岁就很浪  阅读(101)  评论(0)    收藏  举报