概述
public BigInteger(String val, int radix) {
//定义了两个变量一个光标,光标记录着应该要处理的数据索引下标
//另一个numDigits 用来保存需要处理的数字位数 也就是有效长度,比如去掉前导零后的
int cursor = 0, numDigits;
final int len = val.length();//传递进来的字符数组的长度
//如果给定的基数,不在合法范围内,那么抛出异常,不会默认处理
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
throw new NumberFormatException("Radix out of range");
//如果字符串长度为0 也是一种非法的参数
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('+');
//符号- + 只能出现一个,而且还必须是第一个位置,否则都不合法
//根据最后一个的索引与0 进行比较,可以简便的判断符号位是否合法
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;
}
//经过前面的判断,如果有符号位的话,光标的值更新为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
//哪怕他原来设置的负数的0 将会变为0 的标记
if (cursor == len) {
signum = 0;
mag = ZERO.mag;
return;
}
//记录实际需要处理的数据长度以及对符号位使用signum进行记录
numDigits = len - cursor;
signum = sign;
// Pre-allocate array of expected size. May be too large but can
// never be too small. Typically exact.
//根据前面的公式计算实际需要的二进制位数 numDigits需要处理的数字的长度
//bitsPerDigit 里面记录了每个进制1位数需要的二进制位数,但是放大了1024倍,所以还要除以1024 也就是右移10
//真正的值可能是小数个,除以1024之后变成了取整了,然后再加上一,百分百够用,需要的比特位数保存到numBits
long numBits = ((numDigits * bitsPerDigit[radix]) >>> 10) + 1;
if (numBits + 31 >= (1L << 32)) {
reportOverflow();
}
//numWords 记录的是实际需要的int类型数据的个数,也就是数组的长度
//右移5位就是除以32 就是计算数组的长度,除法会取整,防止1个不足32位的时候,就会变成0了所以numBits加上31 之后再除以32
int numWords = (int) (numBits + 31) >>> 5;
//此时创建真正的保存数据的int数组了
int[] magnitude = new int[numWords];
// Process first (potentially short) digit group
//numDigits 需要处理的数字的个数
//digitsPerInt 保存的是每一个int能够保存的指定数制下的字符长度
//如果有余数,说明有一个不足最大长度的位数
//如果没有余数,那么每一组都是刚好能够保存的最大长度
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");
// Process remaining digit groups
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");
// 这个方法是用来累计计算的,方法内部写的很复杂
//其实逻辑很简单,比如一个数字序列1234,求他表示的值是多少
// ( ( (1*10)+2 )*10+3 )*10 +4 = 1234
//这个方法就是用来计算的,只不过每一个位置是一个int 低32位当做数值 高32位当做进位
destructiveMulAdd(magnitude, superRadix, groupVal);
}
// Required for cases where the array was overallocated.
mag = trustedStripLeadingZeroInts(magnitude);
if (mag.length >= MAX_MAG_LENGTH) {
checkRange();
}
}
最后
以上就是儒雅洋葱为你收集整理的java int biginteger_[十六]基础类型BigInteger简介的全部内容,希望文章能够帮你解决java int biginteger_[十六]基础类型BigInteger简介所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复