java int biginteger_[十六]基础类型BigInteger简介

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();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值