文章目录

  • BigInteger
  • BigInteger构造方法
  • 小结
  • BigInteger常见成员方法
  • BigInteger底层存储方式
  • BigDecimal
  • 计算机中的小数
  • BigDecimal的作用
  • BigDecimal的使用
  • BigDecimal底层存储方式
  • 总结


BigInteger

  • 在Java中,整数有四种类型:byte,short,int,long
  • 在底层占用字节个数:byte1字节,short2字节,int4字节,long8字节

long为例:

javastring是多少字节 java integer多少字节_算法


表示

javastring是多少字节 java integer多少字节_System_02

如果超出这个范围,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);
    }
}

计算机中的小数

十进制的小树在计算机的存储如下

javastring是多少字节 java integer多少字节_jvm_03


 

javastring是多少字节 java integer多少字节_java_04

  • 小数部分

javastring是多少字节 java integer多少字节_System_05


如果要将十进制的小树转成二进制,可能会有很长很长,而在java中,float和double所占的字节数有限,超出的部分只能舍弃 --> 不精确 --> 后续计算也会不精确

javastring是多少字节 java integer多少字节_java_06


但有些情况是需要必须精确的,比如贷款买房子,或飞机火箭等精密零件上的计算必须精确

javastring是多少字节 java integer多少字节_算法_07

         

javastring是多少字节 java integer多少字节_算法_08


 

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底层存储方式

javastring是多少字节 java integer多少字节_jvm_09

  • 遍历得到每一个字符
  • 把字符转换成ASCII表中的数值进行存储
  • 负数也会把负号的ASCII表值存储

总结

  • BigDecimal的作用是什么?
  • 表示较大的小数和解决小数运算精度失真的问题。
  • BigDecimal的对象如何获取?
  • BigDecimal bd1 = new BigDecimal("较大的数");
  • BigDecimal bd2 = BigDecimal.valueOf(0.1);
  • 常见操作
  • 加:add
  • 减:subtract
  • 乘:multiply
  • 除:divide(四舍五入:RoundingMode.HALF_UP)