java大数类型BigInteger和BigDecimal中的一些坑事

文章目录

    • 1. BigInteger构造正负数问题
    • 2. BigInteger通过toByteArry()转成字节数组的长度问题
      • 2.1 BigInteger转byte[]的机制简述
      • 2.2 长度问题


在BigInteger与BigDecimal的使用中,除了那些常用的函数,还有一些小坑在等着各位,简单聊一下我碰到的那些小坑。

1. BigInteger构造正负数问题

//通过字符串传入构造方法来获得对应的BigInteger
BigInteger bigInteger = new BigInteger("127");
//byteInteger为[127]
byte[] byteInteger = bigInteger.toByteArray(); 
BigInteger bigInteger2 = new BigInteger("-3");
//byteInteger2也为[127]
byte[] byteInteger2 = bigInteger.toByteArray(); 

从上述代码可以看到,BigInteger对127与-3编码好像是一样的。其实不是的,使用上述构造方法将默认创建正数。当要用BIgInteger构建负数时,应该使用 BigInteger(int signum, byte[] magnitude),其中signum为符号位,可以为-1,0,1,分别代表负、零、正。

//BigInteger对3编码为[3]
byte[] byteBigInteger = {3};
BigInteger bigInteger = new BigInteger(-1,byteBigInteger);
//输出-3
System.out.println(bigInteger);
//byteInteger为[-3]
byte[] byteInteger = bigInteger.toByteArray(); 

2. BigInteger通过toByteArry()转成字节数组的长度问题

2.1 BigInteger转byte[]的机制简述

BigInteger在转成byte[]中号称会返回无符号字节数组,其实也不尽然。一方面在这里byte类型确实是无符号的,正常byte的取值范围是[-128,127],然而在这里取值范围为[0,255];另一方面由于采用了无符号byte,为了表示负数,BIgInteger会强行占用最高位来存符号位。

2.2 长度问题

	BigInteger bigInteger = new BigInteger("127");
	//byteInteger = [127]
	byte[] byteInteger = bigInteger.toByteArray(); 
	
	BigInteger bigInteger2 = new BigInteger("128");
	//byteInteger = [0,-128]
	byte[] byteInteger = bigInteger2.toByteArray(); 

上述现象解释:byte占8位,无符号最大可表示(2^8)-1 = 255,然而Bigteger始终会征用最低高位来存符号,剩下7位最大可表示127,一旦超过127,无符号的byte就需要8位来存,再加上一位符号位,则需要9位,这时候会发生自动拓展的情况,byte[]由长度1变为长度2。
注意:最低高位是指真正存储数据的前一位,例如:上述代码中,存128共使用了2字节中的后9位,存符号的最低高位是从高位往低位的第8位,而不是第1位。 如下图:
java大数类型BigInteger和BigDecimal中的一些坑事_第1张图片


你可能感兴趣的:(Java技术杂谈)