解析java.math.BigInteger类——构造函数
Posted 腾逸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析java.math.BigInteger类——构造函数相关的知识,希望对你有一定的参考价值。
最早由于做作业,结识了java的BigInrger类。读着读着,越来越觉得有趣。后来作业做完,也不忍丢下它,索性把全部代码研究一遍。
开始的时候,一个上午时间最多读懂2个方法。但是还是有滋有味的坚持了下来。下面开始一点点剖开它“隐藏”的秘密。
首先要想搞懂两个问题:BigIngeter类的目的——实现高精度数的存储和计算。基础的实现机理——用int型(32位)数组存储数据。(在代码的注释中有详细说明)
/////////////////////////////////////////////////////////////
BigInteger类中的属性:{
int signum; 符号位,负数是为-1,零时为0,正数是为1
int[] mag; The magnitude of this BigInteger,大数的值}
首先来分析下构造函数 (构造五部曲:1.检查是否符合标准 2.去零 3.mag赋值 4.去mag中零 5.符号位赋值)
1. 使用byte(8位)型数组构造BigInteger:
/////////////////////////////////////////////////////////////////////
public BigInteger(byte[] val) {
if (val.length == 0)
throw new NumberFormatException("Zero length BigInteger");
//传入数组长度为零,报错
if (val[0] < 0) {
mag = makePositive(val);
signum = -1;
//如果数组第一个值为负数,则将数组变正存入mag,signum赋-1
} else {
mag = stripLeadingZeroBytes(val);
//如果非负,则可直接去掉前面无效零,再赋给mag
signum = (mag.length == 0 ? 0 : 1);
}
}
下面看一下具体调用的函数
///////////////////////////////////////////////////////////////////////////
private static int[] stripLeadingZeroBytes(byte a[]) {
int byteLength = a.length;
int keep;
// Find first nonzero byte
for (keep=0; keep<a.length
&& a[keep]==0; keep++)
//找到第一个有效位,并用keep记录下
;
// Allocate new array and copy relevant part
of input array
int intLength = ((byteLength - keep) + 3)/4;
//计算int[]的长度,byte[1/2/3/4]对应int[1]
int[] result = new int[intLength];
int b = byteLength - 1;
for (int i = intLength-1; i >= 0; i--) {
result[i] = a[b--] & 0xff;
//向int[]赋值,&0xff的作用是消除对int前24位的影响
(计算机中使用补码存储数据,如果直接将一个第一位为“1”的byte值赋给int,则前24为将为“1”)
int bytesRemaining = b - keep + 1;
int bytesToTransfer = Math.min(3, bytesRemaining);
for (int j=8; j <= 8*bytesToTransfer; j += 8)
result[i] |= ((a[b--] & 0xff)
<< j);
//进行移位,每次移动8位,再进行或运算
}
return result;
}
//////////////////////////////////////////////////////////////
private static int[] makePositive(byte a[]) {以上是关于解析java.math.BigInteger类——构造函数的主要内容,如果未能解决你的问题,请参考以下文章
java.math.BigInteger 不能转换为 java.math.BigDecimal
java.math.BigInteger 不能转换为 java.lang.Integer
[记录]java.math.biginteger cannot be cast to java.lang.long
如何在不使用 java.math.BigInteger 的情况下在 Java 中处理非常大的数字
java Operator ‘/‘ cannot be applied to ‘java.math.BigInteger‘, ‘int‘