主要是String转int[]
/**
* Translates the String representation of a BigInteger in the
* specified radix into a BigInteger. The String representation
* consists of an optional minus or plus sign followed by a
* sequence of one or more digits in the specified radix. The
* character-to-digit mapping is provided by {@code
* Character.digit}. The String may not contain any extraneous
* characters (whitespace, for example).
*
* @param val String representation of BigInteger.
* @param radix radix to be used in interpreting {@code val}.
* @throws NumberFormatException {@code val} is not a valid representation
* of a BigInteger in the specified radix, or {@code radix} is
* outside the range from {@link Character#MIN_RADIX} to
* {@link Character#MAX_RADIX}, inclusive.
* @see Character#digit
*/
public BigInteger(String val, int radix) {
int cursor = 0, numDigits;
final int len = val.length();
// radix 是否在2-36之间
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
throw new NumberFormatException("Radix out of range");
if (len == 0)
throw new NumberFormatException("Zero length BigInteger");
// Check for at most one leading sign
// 检查是否存在多个“+”“-”符号
// 判断正负
int sign = 1;
int index1 = val.lastIndexOf('-');
int index2 = val.lastIndexOf('+');
if (index1 >= 0) {
if (index1 != 0 || index2 >= 0) {
throw new NumberFormatException("Illegal embedded sign character");
}
sign = -1;
cursor = 1;
} else if (index2 >= 0) {
if (index2 != 0) {
throw new NumberFormatException("Illegal embedded sign character");
}
cursor = 1;
}
if (cursor == len)
throw new NumberFormatException("Zero length BigInteger");
// Skip leading zeros and compute number of digits in magnitude
// 忽略前置的0
while (cursor < len &&
Character.digit(val.charAt(cursor), radix) == 0) {
cursor++;
}
// 字符串内全是0的情况,直接返回0值
if (cursor == len) {
signum = 0;
mag = ZERO.mag;
return;
}
numDigits = len - cursor;
signum = sign;
// 预分配预期大小的数组。可能太大,但决不可能太小。通常精确。
long numBits = ((numDigits * bitsPerDigit[radix]) >>> 10) + 1;
if (numBits + 31 >= (1L << 32)) {
reportOverflow();
}
int numWords = (int) (numBits + 31) >>> 5;
int[] magnitude = new int[numWords];
// Process first (potentially short) digit group
// 计算当前进制(radix)中,数组第一位保存的位数
int firstGroupLen = numDigits % digitsPerInt[radix];
if (firstGroupLen == 0)
firstGroupLen = digitsPerInt[radix];
String group = val.substring(cursor, cursor += firstGroupLen);
magnitude[numWords - 1] = Integer.parseInt(group, radix);
// 检查第一个值是否合法
if (magnitude[numWords - 1] < 0)
throw new NumberFormatException("Illegal digit");
// 处理剩余的数字
// 获取该进制最大位数
int superRadix = intRadix[radix];
int groupVal = 0;
while (cursor < len) {
group = val.substring(cursor, cursor += digitsPerInt[radix]);
groupVal = Integer.parseInt(group, radix);
if (groupVal < 0)
throw new NumberFormatException("Illegal digit");
// 向最后一位进行加法操作,再进行一次进位计算
destructiveMulAdd(magnitude, superRadix, groupVal);
}
// Required for cases where the array was overallocated.
// 去掉开头的0
mag = trustedStripLeadingZeroInts(magnitude);
if (mag.length >= MAX_MAG_LENGTH) {
checkRange();
}
}
/*
* 整数模拟,对应radix(进制)的最大位数和指数方
* intRadix = radix^digitsPerInt[radix]
*/
private static int digitsPerInt[] = {0, 0, 30, 19, 15, 13, 11,
11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
private static int intRadix[] = {0, 0,
0x40000000, 0x4546b3db, 0x40000000, 0x48c27395, 0x159fd800,
0x75db9c97, 0x40000000, 0x17179149, 0x3b9aca00, 0xcc6db61,
0x19a10000, 0x309f1021, 0x57f6c100, 0xa2f1b6f, 0x10000000,
0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d,
0x6c20a40, 0x8d2d931, 0xb640000, 0xe8d4a51, 0x1269ae40,
0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x39aa400
};
// Multiply x array times word y in place, and add word z
// 计算低位是否需要向高增递交进位
private static void destructiveMulAdd(int[] x, int y, int z) {
// Perform the multiplication word by word
long ylong = y & LONG_MASK;
long zlong = z & LONG_MASK;
int len = x.length;
long product = 0;
long carry = 0;
// 计算值后保存int值到数组中,再计算向高位递交的值
for (int i = len-1; i >= 0; i--) {
product = ylong * (x[i] & LONG_MASK) + carry;
x[i] = (int)product;
carry = product >>> 32;
}
// Perform the addition
// 向最后一位进行加法操作,再进行一次进位计算
long sum = (x[len-1] & LONG_MASK) + zlong;
x[len-1] = (int)sum;
carry = sum >>> 32;
for (int i = len-2; i >= 0; i--) {
sum = (x[i] & LONG_MASK) + carry;
x[i] = (int)sum;
carry = sum >>> 32;
}
}
/**
* Returns the input array stripped of any leading zero bytes.
* Since the source is trusted the copying may be skipped.
* 去掉开头的0
*/
private static int[] trustedStripLeadingZeroInts(int val[]) {
int vlen = val.length;
int keep;
// Find first nonzero byte
for (keep = 0; keep < vlen && val[keep] == 0; keep++)
;
return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen);
}
在业务处理中,还遇到过要将char[]转成BigInteger的需求
/*
* Constructs a new BigInteger using a char array with radix=10.
* Sign is precalculated outside and not allowed in the val. The {@code val}
* array is assumed to be unchanged for the duration of the constructor
* call.
* char[]数组,需要填写正负参数,只能定义10进制内容,还需要确定数组长度
*/
BigInteger(char[] val, int sign, int len) {
int cursor = 0, numDigits;
// Skip leading zeros and compute number of digits in magnitude
while (cursor < len && Character.digit(val[cursor], 10) == 0) {
cursor++;
}
if (cursor == len) {
signum = 0;
mag = ZERO.mag;
return;
}
numDigits = len - cursor;
signum = sign;
// 预先估计数组大小
int numWords;
if (len < 10) {
numWords = 1;
} else {
long numBits = ((numDigits * bitsPerDigit[10]) >>> 10) + 1;
if (numBits + 31 >= (1L << 32)) {
reportOverflow();
}
numWords = (int) (numBits + 31) >>> 5;
}
int[] magnitude = new int[numWords];
// 处理第一位
int firstGroupLen = numDigits % digitsPerInt[10];
if (firstGroupLen == 0)
firstGroupLen = digitsPerInt[10];
magnitude[numWords - 1] = parseInt(val, cursor, cursor += firstGroupLen);
// 处理余下的
while (cursor < len) {
int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]);
destructiveMulAdd(magnitude, intRadix[10], groupVal);
}
mag = trustedStripLeadingZeroInts(magnitude);
if (mag.length >= MAX_MAG_LENGTH) {
checkRange();
}
}
long转BigInteger也是比较常见的
/**
* 将long转成BigInteger,当数值大于int范围时,除以2^32,商为高位,地位直接转int格式
*/
private BigInteger(long val) {
if (val < 0) {
val = -val;
signum = -1;
} else {
signum = 1;
}
int highWord = (int)(val >>> 32);// 除以2^32,获得进位
if (highWord == 0) {
mag = new int[1];
mag[0] = (int)val;
} else {
mag = new int[2];
mag[0] = highWord;
mag[1] = (int)val;
}
}