JDK中BigInteger的代码实现
package java.math;
import I;
import [I;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream.PutField;
import java.io.ObjectStreamField;
import java.io.StreamCorruptedException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Random;
import sun.misc.Unsafe;
public class BigInteger extends Number
implements Comparable<BigInteger>
{
final int signum;
final int[] mag;
@Deprecated
private int bitCount;
@Deprecated
private int bitLength;
@Deprecated
private int lowestSetBit;
@Deprecated
private int firstNonzeroIntNum;
static final long LONG_MASK = 4294967295L;
private static long[] bitsPerDigit;
private static final int SMALL_PRIME_THRESHOLD = 95;
private static final int DEFAULT_PRIME_CERTAINTY = 100;
private static final BigInteger SMALL_PRIME_PRODUCT;
private static volatile Random staticRandom;
private static final int MAX_CONSTANT = 16;
private static BigInteger[] posConst;
private static BigInteger[] negConst;
public static final BigInteger ZERO;
public static final BigInteger ONE;
private static final BigInteger TWO;
public static final BigInteger TEN;
static int[] bnExpModThreshTable;
private static String[] zeros;
private static int[] digitsPerLong;
private static BigInteger[] longRadix;
private static int[] digitsPerInt;
private static int[] intRadix;
private static final long serialVersionUID = -8287574255936472291L;
private static final ObjectStreamField[] serialPersistentFields;
private static final Unsafe unsafe;
private static final long signumOffset;
private static final long magOffset;
public BigInteger(byte[] paramArrayOfByte)
{
if (paramArrayOfByte.length == 0)
throw new NumberFormatException("Zero length BigInteger");
if (paramArrayOfByte[0] < 0)
{
this.mag = makePositive(paramArrayOfByte);
this.signum = -1;
}
else
{
this.mag = stripLeadingZeroBytes(paramArrayOfByte);
this.signum = ((this.mag.length == 0) ? 0 : 1);
}
}
private BigInteger(int[] paramArrayOfInt)
{
if (paramArrayOfInt.length == 0)
throw new NumberFormatException("Zero length BigInteger");
if (paramArrayOfInt[0] < 0)
{
this.mag = makePositive(paramArrayOfInt);
this.signum = -1;
}
else
{
this.mag = trustedStripLeadingZeroInts(paramArrayOfInt);
this.signum = ((this.mag.length == 0) ? 0 : 1);
}
}
public BigInteger(int paramInt, byte[] paramArrayOfByte)
{
this.mag = stripLeadingZeroBytes(paramArrayOfByte);
if ((paramInt < -1) || (paramInt > 1))
throw new NumberFormatException("Invalid signum value");
if (this.mag.length == 0)
{
this.signum = 0;
}
else
{
if (paramInt == 0)
throw new NumberFormatException("signum-magnitude mismatch");
this.signum = paramInt;
}
}
private BigInteger(int paramInt, int[] paramArrayOfInt)
{
this.mag = stripLeadingZeroInts(paramArrayOfInt);
if ((paramInt < -1) || (paramInt > 1))
throw new NumberFormatException("Invalid signum value");
if (this.mag.length == 0)
{
this.signum = 0;
}
else
{
if (paramInt == 0)
throw new NumberFormatException("signum-magnitude mismatch");
this.signum = paramInt;
}
}
public BigInteger(String paramString, int paramInt)
{
int i = 0;
int k = paramString.length();
if ((paramInt < 2) || (paramInt > 36))
throw new NumberFormatException("Radix out of range");
if (paramString.length() == 0)
throw new NumberFormatException("Zero length BigInteger");
int l = 1;
int i1 = paramString.lastIndexOf("-");
if (i1 != -1)
if (i1 == 0)
{
if (paramString.length() == 1)
throw new NumberFormatException("Zero length BigInteger");
l = -1;
i = 1;
}
else
{
throw new NumberFormatException("Illegal embedded minus sign");
}
while ((i < k) && (Character.digit(paramString.charAt(i), paramInt) == 0))
++i;
if (i == k)
{
this.mag = ZERO.mag;
this.signum = 0;
return;
}
int j = k - i;
this.signum = l;
int i2 = (int)((j * bitsPerDigit[paramInt] >>> 10) + 1L);
int i3 = i2 + 31 >>> 5;
int[] arrayOfInt = new int[i3];
int i4 = j % digitsPerInt[paramInt];
if (i4 == 0)
i4 = digitsPerInt[paramInt];
String str = paramString.substring(i, i += i4);
arrayOfInt[(arrayOfInt.length - 1)] = Integer.parseInt(str, paramInt);
if (arrayOfInt[(arrayOfInt.length - 1)] < 0)
throw new NumberFormatException("Illegal digit");
int i5 = intRadix[paramInt];
int i6 = 0;
while (i < paramString.length())
{
str = paramString.substring(i, i += digitsPerInt[paramInt]);
i6 = Integer.parseInt(str, paramInt);
if (i6 < 0)
throw new NumberFormatException("Illegal digit");
destructiveMulAdd(arrayOfInt, i5, i6);
}
this.mag = trustedStripLeadingZeroInts(arrayOfInt);
}
BigInteger(char[] paramArrayOfChar)
{
int i = 0;
int k = paramArrayOfChar.length;
int l = 1;
if (paramArrayOfChar[0] == '-')
{
if (k == 1)
throw new NumberFormatException("Zero length BigInteger");
l = -1;
}
for (i = 1; (i < k) && (Character.digit(paramArrayOfChar[i], 10) == 0); ++i);
if (i == k)
{
this.signum = 0;
this.mag = ZERO.mag;
return;
}
int j = k - i;
this.signum = l;
int i1;
if (k < 10)
{
i1 = 1;
}
else
{
int i2 = (int)((j * bitsPerDigit[10] >>> 10) + 1L);
i1 = i2 + 31 >>> 5;
}
int[] arrayOfInt = new int[i1];
int i3 = j % digitsPerInt[10];
if (i3 == 0)
i3 = digitsPerInt[10];
arrayOfInt[(i1 - 1)] = parseInt(paramArrayOfChar, i, i += i3);
while (i < k)
{
int i4 = parseInt(paramArrayOfChar, i, i += digitsPerInt[10]);
destructiveMulAdd(arrayOfInt, intRadix[10], i4);
}
this.mag = trustedStripLeadingZeroInts(arrayOfInt);
}
private int parseInt(char[] paramArrayOfChar, int paramInt1, int paramInt2)
{
int i = Character.digit(paramArrayOfChar[(paramInt1++)], 10);
if (i == -1)
throw new NumberFormatException(new String(paramArrayOfChar));
for (int j = paramInt1; j < paramInt2; ++j)
{
int k = Character.digit(paramArrayOfChar[j], 10);
if (k == -1)
throw new NumberFormatException(new String(paramArrayOfChar));
i = 10 * i + k;
}
return i;
}
private static void destructiveMulAdd(int[] paramArrayOfInt, int paramInt1, int paramInt2)
{
long l1 = paramInt1 & 0xFFFFFFFF;
long l2 = paramInt2 & 0xFFFFFFFF;
int i = paramArrayOfInt.length;
long l3 = 0L;
long l4 = 0L;
for (int j = i - 1; j >= 0; --j)
{
l3 = l1 * (paramArrayOfInt[j] & 0xFFFFFFFF) + l4;
paramArrayOfInt[j] = (int)l3;
l4 = l3 >>> 32;
}
long l5 = (paramArrayOfInt[(i - 1)] & 0xFFFFFFFF) + l2;
paramArrayOfInt[(i - 1)] = (int)l5;
l4 = l5 >>> 32;
for (int k = i - 2; k >= 0; --k)
{
l5 = (paramArrayOfInt[k] & 0xFFFFFFFF) + l4;
paramArrayOfInt[k] = (int)l5;
l4 = l5 >>> 32;
}
}
public BigInteger(String paramString)
{
this(paramString, 10);
}
public BigInteger(int paramInt, Random paramRandom)
{
this(1, randomBits(paramInt, paramRandom));
}
private static byte[] randomBits(int paramInt, Random paramRandom)
{
if (paramInt < 0)
throw new IllegalArgumentException("numBits must be non-negative");
int i = (int)((paramInt + 7L) / 8L);
byte[] arrayOfByte = new byte[i];
if (i > 0)
{
paramRandom.nextBytes(arrayOfByte);
int j = 8 * i - paramInt;
int tmp49_48 = 0;
byte[] tmp49_47 = arrayOfByte;
tmp49_47[tmp49_48] = (byte)(tmp49_47[tmp49_48] & (1 << 8 - j) - 1);
}
return arrayOfByte;
}
public BigInteger(int paramInt1, int paramInt2, Random paramRandom)
{
if (paramInt1 < 2)
throw new ArithmeticException("bitLength < 2");
BigInteger localBigInteger = (paramInt1 < 95) ? smallPrime(paramInt1, paramInt2, paramRandom) : largePrime(paramInt1, paramInt2, paramRandom);
this.signum = 1;
this.mag = localBigInteger.mag;
}
public static BigInteger probablePrime(int paramInt, Random paramRandom)
{
if (paramInt < 2)
throw new ArithmeticException("bitLength < 2");
return ((paramInt < 95) ? smallPrime(paramInt, 100, paramRandom) : largePrime(paramInt, 100, paramRandom));
}
private static BigInteger smallPrime(int paramInt1, int paramInt2, Random paramRandom)
{
int i = paramInt1 + 31 >>> 5;
int[] arrayOfInt = new int[i];
int j = 1 << (paramInt1 + 31 & 0x1F);
int k = (j << 1) - 1;
while (true)
{
for (int l = 0; l < i; ++l)
arrayOfInt[l] = paramRandom.nextInt();
arrayOfInt[0] = (arrayOfInt[0] & k | j);
if (paramInt1 > 2)
arrayOfInt[(i - 1)] |= 1;
BigInteger localBigInteger = new BigInteger(arrayOfInt, 1);
if (paramInt1 > 6)
{
long l1 = localBigInteger.remainder(SMALL_PRIME_PRODUCT).longValue();
if ((l1 % 3L == 0L) || (l1 % 5L == 0L) || (l1 % 7L == 0L) || (l1 % 11L == 0L) || (l1 % 13L == 0L) || (l1 % 17L == 0L) || (l1 % 19L == 0L) || (l1 % 23L == 0L) || (l1 % 29L == 0L) || (l1 % 31L == 0L) || (l1 % 37L == 0L))
continue;
if (l1 % 41L == 0L)
continue;
}
if (paramInt1 < 4)
return localBigInteger;
if (localBigInteger.primeToCertainty(paramInt2, paramRandom))
return localBigInteger;
}
}
private static BigInteger largePrime(int paramInt1, int paramInt2, Random paramRandom)
{
BigInteger localBigInteger1 = new BigInteger(paramInt1, paramRandom).setBit(paramInt1 - 1);
localBigInteger1.mag[(localBigInteger1.mag.length - 1)] &= -2;
int i = paramInt1 / 20 * 64;
BitSieve localBitSieve = new BitSieve(localBigInteger1, i);
for (BigInteger localBigInteger2 = localBitSieve.retrieve(localBigInteger1, paramInt2, paramRandom); (localBigInteger2 == null) || (localBigInteger2.bitLength() != paramInt1); localBigInteger2 = localBitSieve.retrieve(localBigInteger1, paramInt2, paramRandom))
{
localBigInteger1 = localBigInteger1.add(valueOf(2 * i));
if (localBigInteger1.bitLength() != paramInt1)
localBigInteger1 = new BigInteger(paramInt1, paramRandom).setBit(paramInt1 - 1);
localBigInteger1.mag[(localBigInteger1.mag.length - 1)] &= -2;
localBitSieve = new BitSieve(localBigInteger1, i);
}
return localBigInteger2;
}
public BigInteger nextProbablePrime()
{
if (this.signum < 0)
throw new ArithmeticException("start < 0: " + this);
if ((this.signum == 0) || (equals(ONE)))
return TWO;
BigInteger localBigInteger1 = add(ONE);
if (localBigInteger1.bitLength() < 95)
{
if (!(localBigInteger1.testBit(0)));
for (localBigInteger1 = localBigInteger1.add(ONE); ; localBigInteger1 = localBigInteger1.add(TWO))
{
while (localBigInteger1.bitLength() > 6)
{
long l = localBigInteger1.remainder(SMALL_PRIME_PRODUCT).longValue();
if ((l % 3L != 0L) && (l % 5L != 0L) && (l % 7L != 0L) && (l % 11L != 0L) && (l % 13L != 0L) && (l % 17L != 0L) && (l % 19L != 0L) && (l % 23L != 0L) && (l % 29L != 0L) && (l % 31L != 0L) && (l % 37L != 0L) && (l % 41L != 0L))
break;
localBigInteger1 = localBigInteger1.add(TWO);
}
if (localBigInteger1.bitLength() < 4)
return localBigInteger1;
if (localBigInteger1.primeToCertainty(100, null))
return localBigInteger1;
}
}
if (localBigInteger1.testBit(0))
localBigInteger1 = localBigInteger1.subtract(ONE);
int i = localBigInteger1.bitLength() / 20 * 64;
while (true)
{
BitSieve localBitSieve = new BitSieve(localBigInteger1, i);
BigInteger localBigInteger2 = localBitSieve.retrieve(localBigInteger1, 100, null);
if (localBigInteger2 != null)
return localBigInteger2;
localBigInteger1 = localBigInteger1.add(valueOf(2 * i));
}
}
boolean primeToCertainty(int paramInt, Random paramRandom)
{
int i = 0;
int j = (Math.min(paramInt, 2147483646) + 1) / 2;
int k = bitLength();
if (k < 100)
{
i = 50;
i = (j < i) ? j : i;
return passesMillerRabin(i, paramRandom);
}
if (k < 256)
i = 27;
else if (k < 512)
i = 15;
else if (k < 768)
i = 8;
else if (k < 1024)
i = 4;
else
i = 2;
i = (j < i) ? j : i;
return ((passesMillerRabin(i, paramRandom)) && (passesLucasLehmer()));
}
private boolean passesLucasLehmer()
{
BigInteger localBigInteger1 = add(ONE);
for (int i = 5; jacobiSymbol(i, this) != -1; i = (i < 0) ? Math.abs(i) + 2 : -(i + 2));
BigInteger localBigInteger2 = lucasLehmerSequence(i, localBigInteger1, this);
return localBigInteger2.mod(this).equals(ZERO);
}
private static int jacobiSymbol(int paramInt, BigInteger paramBigInteger)
{
if (paramInt == 0)
return 0;
int i = 1;
int j = paramBigInteger.mag[(paramBigInteger.mag.length - 1)];
int k;
if (paramInt < 0)
{
paramInt = -paramInt;
k = j & 0x7;
if ((k == 3) || (k == 7))
i = -i;
}
while ((paramInt & 0x3) == 0)
paramInt >>= 2;
if ((paramInt & 0x1) == 0)
{
paramInt >>= 1;
if (((j ^ j >> 1) & 0x2) != 0)
i = -i;
}
if (paramInt == 1)
return i;
if ((paramInt & j & 0x2) != 0)
i = -i;
j = paramBigInteger.mod(valueOf(paramInt)).intValue();
while (j != 0)
{
while ((j & 0x3) == 0)
j >>= 2;
if ((j & 0x1) == 0)
{
j >>= 1;
if (((paramInt ^ paramInt >> 1) & 0x2) != 0)
i = -i;
}
if (j == 1)
return i;
assert (j < paramInt);
k = j;
j = paramInt;
paramInt = k;
if ((j & paramInt & 0x2) != 0)
i = -i;
j %= paramInt;
}
return 0;
}
private static BigInteger lucasLehmerSequence(int paramInt, BigInteger paramBigInteger1, BigInteger paramBigInteger2)
{
BigInteger localBigInteger1 = valueOf(paramInt);
Object localObject1 = ONE;
Object localObject2 = ONE;
for (int i = paramBigInteger1.bitLength() - 2; i >= 0; --i)
{
BigInteger localBigInteger2 = ((BigInteger)localObject1).multiply((BigInteger)localObject2).mod(paramBigInteger2);
BigInteger localBigInteger3 = ((BigInteger)localObject2).square().add(localBigInteger1.multiply(((BigInteger)localObject1).square())).mod(paramBigInteger2);
if (localBigInteger3.testBit(0))
localBigInteger3 = localBigInteger3.subtract(paramBigInteger2);
localBigInteger3 = localBigInteger3.shiftRight(1);
localObject1 = localBigInteger2;
localObject2 = localBigInteger3;
if (!(paramBigInteger1.testBit(i)))
continue;
localBigInteger2 = ((BigInteger)localObject1).add((BigInteger)localObject2).mod(paramBigInteger2);
if (localBigInteger2.testBit(0))
localBigInteger2 = localBigInteger2.subtract(paramBigInteger2);
localBigInteger2 = localBigInteger2.shiftRight(1);
localBigInteger3 = ((BigInteger)localObject2).add(localBigInteger1.multiply((BigInteger)localObject1)).mod(paramBigInteger2);
if (localBigInteger3.testBit(0))
localBigInteger3 = localBigInteger3.subtract(paramBigInteger2);
localBigInteger3 = localBigInteger3.shiftRight(1);
localObject1 = localBigInteger2;
localObject2 = localBigInteger3;
}
return ((BigInteger)(BigInteger)localObject1);
}
private static Random getSecureRandom()
{
if (staticRandom == null)
staticRandom = new SecureRandom();
return staticRandom;
}
private boolean passesMillerRabin(int paramInt, Random paramRandom)
{
BigInteger localBigInteger1 = subtract(ONE);
BigInteger localBigInteger2 = localBigInteger1;
int i = localBigInteger2.getLowestSetBit();
localBigInteger2 = localBigInteger2.shiftRight(i);
if (paramRandom == null)
paramRandom = getSecureRandom();
for (int j = 0; j < paramInt; ++j)
{
BigInteger localBigInteger3;
do
localBigInteger3 = new BigInteger(bitLength(), paramRandom);
while ((localBigInteger3.compareTo(ONE) <= 0) || (localBigInteger3.compareTo(this) >= 0));
int k = 0;
for (BigInteger localBigInteger4 = localBigInteger3.modPow(localBigInteger2, this); (((k != 0) || (!(localBigInteger4.equals(ONE))))) && (!(localBigInteger4.equals(localBigInteger1))); localBigInteger4 = localBigInteger4.modPow(TWO, this))
if (((k > 0) && (localBigInteger4.equals(ONE))) || (++k == i))
return false;
}
return true;
}
BigInteger(int[] paramArrayOfInt, int paramInt)
{
this.signum = ((paramArrayOfInt.length == 0) ? 0 : paramInt);
this.mag = paramArrayOfInt;
}
private BigInteger(byte[] paramArrayOfByte, int paramInt)
{
this.signum = ((paramArrayOfByte.length == 0) ? 0 : paramInt);
this.mag = stripLeadingZeroBytes(paramArrayOfByte);
}
public static BigInteger valueOf(long paramLong)
{
if (paramLong == 0L)
return ZERO;
if ((paramLong > 0L) && (paramLong <= 16L))
return posConst[(int)paramLong];
if ((paramLong < 0L) && (paramLong >= -16L))
return negConst[(int)(-paramLong)];
return new BigInteger(paramLong);
}
private BigInteger(long paramLong)
{
if (paramLong < 0L)
{
paramLong = -paramLong;
this.signum = -1;
}
else
{
this.signum = 1;
}
int i = (int)(paramLong >>> 32);
if (i == 0)
{
this.mag = new int[1];
this.mag[0] = (int)paramLong;
}
else
{
this.mag = new int[2];
this.mag[0] = i;
this.mag[1] = (int)paramLong;
}
}
private static BigInteger valueOf(int[] paramArrayOfInt)
{
return new BigInteger(paramArrayOfInt);
}
public BigInteger add(BigInteger paramBigInteger)
{
if (paramBigInteger.signum == 0)
return this;
if (this.signum == 0)
return paramBigInteger;
if (paramBigInteger.signum == this.signum)
return new BigInteger(add(this.mag, paramBigInteger.mag), this.signum);
int i = compareMagnitude(paramBigInteger);
if (i == 0)
return ZERO;
int[] arrayOfInt = (i > 0) ? subtract(this.mag, paramBigInteger.mag) : subtract(paramBigInteger.mag, this.mag);
arrayOfInt = trustedStripLeadingZeroInts(arrayOfInt);
return new BigInteger(arrayOfInt, (i == this.signum) ? 1 : -1);
}
private static int[] add(int[] paramArrayOfInt1, int[] paramArrayOfInt2)
{
if (paramArrayOfInt1.length < paramArrayOfInt2.length)
{
int[] arrayOfInt1 = paramArrayOfInt1;
paramArrayOfInt1 = paramArrayOfInt2;
paramArrayOfInt2 = arrayOfInt1;
}
int i = paramArrayOfInt1.length;
int j = paramArrayOfInt2.length;
int[] arrayOfInt2 = new int[i];
long l = 0L;
while (j > 0)
{
l = (paramArrayOfInt1[(--i)] & 0xFFFFFFFF) + (paramArrayOfInt2[(--j)] & 0xFFFFFFFF) + (l >>> 32);
arrayOfInt2[i] = (int)l;
}
for (int k = (l >>> 32 != 0L) ? 1 : 0; (i > 0) && (k != 0); k = ((arrayOfInt2[(--i)] = paramArrayOfInt1[i] + 1) == 0) ? 1 : 0);
while (i > 0)
arrayOfInt2[(--i)] = paramArrayOfInt1[i];
if (k != 0)
{
int[] arrayOfInt3 = new int[arrayOfInt2.length + 1];
System.arraycopy(arrayOfInt2, 0, arrayOfInt3, 1, arrayOfInt2.length);
arrayOfInt3[0] = 1;
return arrayOfInt3;
}
return arrayOfInt2;
}
public BigInteger subtract(BigInteger paramBigInteger)
{
if (paramBigInteger.signum == 0)
return this;
if (this.signum == 0)
return paramBigInteger.negate();
if (paramBigInteger.signum != this.signum)
return new BigInteger(add(this.mag, paramBigInteger.mag), this.signum);
int i = compareMagnitude(paramBigInteger);
if (i == 0)
return ZERO;
int[] arrayOfInt = (i > 0) ? subtract(this.mag, paramBigInteger.mag) : subtract(paramBigInteger.mag, this.mag);
arrayOfInt = trustedStripLeadingZeroInts(arrayOfInt);
return new BigInteger(arrayOfInt, (i == this.signum) ? 1 : -1);
}
private static int[] subtract(int[] paramArrayOfInt1, int[] paramArrayOfInt2)
{
int i = paramArrayOfInt1.length;
int[] arrayOfInt = new int[i];
int j = paramArrayOfInt2.length;
long l = 0L;
while (j > 0)
{
l = (paramArrayOfInt1[(--i)] & 0xFFFFFFFF) - (paramArrayOfInt2[(--j)] & 0xFFFFFFFF) + (l >> 32);
arrayOfInt[i] = (int)l;
}
for (int k = (l >> 32 != 0L) ? 1 : 0; (i > 0) && (k != 0); k = ((arrayOfInt[(--i)] = paramArrayOfInt1[i] - 1) == -1) ? 1 : 0);
while (i > 0)
arrayOfInt[(--i)] = paramArrayOfInt1[i];
return arrayOfInt;
}
public BigInteger multiply(BigInteger paramBigInteger)
{
if ((paramBigInteger.signum == 0) || (this.signum == 0))
return ZERO;
int[] arrayOfInt = multiplyToLen(this.mag, this.mag.length, paramBigInteger.mag, paramBigInteger.mag.length, null);
arrayOfInt = trustedStripLeadingZeroInts(arrayOfInt);
return new BigInteger(arrayOfInt, (this.signum == paramBigInteger.signum) ? 1 : -1);
}
BigInteger multiply(long paramLong)
{
if ((paramLong == 0L) || (this.signum == 0))
return ZERO;
assert (paramLong != -9223372036854775808L);
int i = (paramLong > 0L) ? this.signum : -this.signum;
if (paramLong < 0L)
paramLong = -paramLong;
long l1 = paramLong >>> 32;
long l2 = paramLong & 0xFFFFFFFF;
int j = this.mag.length;
int[] arrayOfInt1 = this.mag;
int[] arrayOfInt2 = (l1 == 0L) ? new int[j + 1] : new int[j + 2];
long l3 = 0L;
int k = arrayOfInt2.length - 1;
long l4;
for (int l = j - 1; l >= 0; --l)
{
l4 = (arrayOfInt1[l] & 0xFFFFFFFF) * l2 + l3;
arrayOfInt2[(k--)] = (int)l4;
l3 = l4 >>> 32;
}
arrayOfInt2[k] = (int)l3;
if (l1 != 0L)
{
l3 = 0L;
k = arrayOfInt2.length - 2;
for (l = j - 1; l >= 0; --l)
{
l4 = (arrayOfInt1[l] & 0xFFFFFFFF) * l1 + (arrayOfInt2[k] & 0xFFFFFFFF) + l3;
arrayOfInt2[(k--)] = (int)l4;
l3 = l4 >>> 32;
}
arrayOfInt2[0] = (int)l3;
}
if (l3 == 0L)
arrayOfInt2 = Arrays.copyOfRange(arrayOfInt2, 1, arrayOfInt2.length);
return new BigInteger(arrayOfInt2, i);
}
private int[] multiplyToLen(int[] paramArrayOfInt1, int paramInt1, int[] paramArrayOfInt2, int paramInt2, int[] paramArrayOfInt3)
{
int i = paramInt1 - 1;
int j = paramInt2 - 1;
if ((paramArrayOfInt3 == null) || (paramArrayOfInt3.length < paramInt1 + paramInt2))
paramArrayOfInt3 = new int[paramInt1 + paramInt2];
long l1 = 0L;
int k = j;
for (int l = j + 1 + i; k >= 0; --l)
{
long l2 = (paramArrayOfInt2[k] & 0xFFFFFFFF) * (paramArrayOfInt1[i] & 0xFFFFFFFF) + l1;
paramArrayOfInt3[l] = (int)l2;
l1 = l2 >>> 32;
--k;
}
paramArrayOfInt3[i] = (int)l1;
for (k = i - 1; k >= 0; --k)
{
l1 = 0L;
l = j;
for (int i1 = j + 1 + k; l >= 0; --i1)
{
long l3 = (paramArrayOfInt2[l] & 0xFFFFFFFF) * (paramArrayOfInt1[k] & 0xFFFFFFFF) + (paramArrayOfInt3[i1] & 0xFFFFFFFF) + l1;
paramArrayOfInt3[i1] = (int)l3;
l1 = l3 >>> 32;
--l;
}
paramArrayOfInt3[k] = (int)l1;
}
return paramArrayOfInt3;
}
private BigInteger square()
{
if (this.signum == 0)
return ZERO;
int[] arrayOfInt = squareToLen(this.mag, this.mag.length, null);
return new BigInteger(trustedStripLeadingZeroInts(arrayOfInt), 1);
}
private static final int[] squareToLen(int[] paramArrayOfInt1, int paramInt, int[] paramArrayOfInt2)
{
int i = paramInt << 1;
if ((paramArrayOfInt2 == null) || (paramArrayOfInt2.length < i))
paramArrayOfInt2 = new int[i];
int j = 0;
int k = 0;
int l = 0;
while (k < paramInt)
{
long l1 = paramArrayOfInt1[k] & 0xFFFFFFFF;
long l2 = l1 * l1;
paramArrayOfInt2[(l++)] = (j << 31 | (int)(l2 >>> 33));
paramArrayOfInt2[(l++)] = (int)(l2 >>> 1);
j = (int)l2;
++k;
}
k = paramInt;
for (l = 1; k > 0; l += 2)
{
int i1 = paramArrayOfInt1[(k - 1)];
i1 = mulAdd(paramArrayOfInt2, paramArrayOfInt1, l, k - 1, i1);
addOne(paramArrayOfInt2, l - 1, k, i1);
--k;
}
primitiveLeftShift(paramArrayOfInt2, i, 1);
paramArrayOfInt2[(i - 1)] |= paramArrayOfInt1[(paramInt - 1)] & 0x1;
return paramArrayOfInt2;
}
public BigInteger divide(BigInteger paramBigInteger)
{
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger();
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(this.mag);
MutableBigInteger localMutableBigInteger3 = new MutableBigInteger(paramBigInteger.mag);
localMutableBigInteger2.divide(localMutableBigInteger3, localMutableBigInteger1);
return localMutableBigInteger1.toBigInteger(this.signum * paramBigInteger.signum);
}
public BigInteger[] divideAndRemainder(BigInteger paramBigInteger)
{
BigInteger[] arrayOfBigInteger = new BigInteger[2];
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger();
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(this.mag);
MutableBigInteger localMutableBigInteger3 = new MutableBigInteger(paramBigInteger.mag);
MutableBigInteger localMutableBigInteger4 = localMutableBigInteger2.divide(localMutableBigInteger3, localMutableBigInteger1);
arrayOfBigInteger[0] = localMutableBigInteger1.toBigInteger(this.signum * paramBigInteger.signum);
arrayOfBigInteger[1] = localMutableBigInteger4.toBigInteger(this.signum);
return arrayOfBigInteger;
}
public BigInteger remainder(BigInteger paramBigInteger)
{
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger();
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(this.mag);
MutableBigInteger localMutableBigInteger3 = new MutableBigInteger(paramBigInteger.mag);
return localMutableBigInteger2.divide(localMutableBigInteger3, localMutableBigInteger1).toBigInteger(this.signum);
}
public BigInteger pow(int paramInt)
{
if (paramInt < 0)
throw new ArithmeticException("Negative exponent");
if (this.signum == 0)
return ((paramInt == 0) ? ONE : this);
int i = ((this.signum < 0) && ((paramInt & 0x1) == 1)) ? -1 : 1;
int[] arrayOfInt1 = this.mag;
int[] arrayOfInt2 = { 1 };
while (paramInt != 0)
{
if ((paramInt & 0x1) == 1)
{
arrayOfInt2 = multiplyToLen(arrayOfInt2, arrayOfInt2.length, arrayOfInt1, arrayOfInt1.length, null);
arrayOfInt2 = trustedStripLeadingZeroInts(arrayOfInt2);
}
if (paramInt >>>= 1 == 0)
continue;
arrayOfInt1 = squareToLen(arrayOfInt1, arrayOfInt1.length, null);
arrayOfInt1 = trustedStripLeadingZeroInts(arrayOfInt1);
}
return new BigInteger(arrayOfInt2, i);
}
public BigInteger gcd(BigInteger paramBigInteger)
{
if (paramBigInteger.signum == 0)
return abs();
if (this.signum == 0)
return paramBigInteger.abs();
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger(this);
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(paramBigInteger);
MutableBigInteger localMutableBigInteger3 = localMutableBigInteger1.hybridGCD(localMutableBigInteger2);
return localMutableBigInteger3.toBigInteger(1);
}
static int bitLengthForInt(int paramInt)
{
return (32 - Integer.numberOfLeadingZeros(paramInt));
}
private static int[] leftShift(int[] paramArrayOfInt, int paramInt1, int paramInt2)
{
int i = paramInt2 >>> 5;
int j = paramInt2 & 0x1F;
int k = bitLengthForInt(paramArrayOfInt[0]);
if (paramInt2 <= 32 - k)
{
primitiveLeftShift(paramArrayOfInt, paramInt1, j);
return paramArrayOfInt;
}
if (j <= 32 - k)
{
arrayOfInt = new int[i + paramInt1];
for (int l = 0; l < paramInt1; ++l)
arrayOfInt[l] = paramArrayOfInt[l];
primitiveLeftShift(arrayOfInt, arrayOfInt.length, j);
return arrayOfInt;
}
int[] arrayOfInt = new int[i + paramInt1 + 1];
for (int i1 = 0; i1 < paramInt1; ++i1)
arrayOfInt[i1] = paramArrayOfInt[i1];
primitiveRightShift(arrayOfInt, arrayOfInt.length, 32 - j);
return arrayOfInt;
}
static void primitiveRightShift(int[] paramArrayOfInt, int paramInt1, int paramInt2)
{
int i = 32 - paramInt2;
int j = paramInt1 - 1;
int k = paramArrayOfInt[j];
while (j > 0)
{
int l = k;
k = paramArrayOfInt[(j - 1)];
paramArrayOfInt[j] = (k << i | l >>> paramInt2);
--j;
}
paramArrayOfInt[0] >>>= paramInt2;
}
static void primitiveLeftShift(int[] paramArrayOfInt, int paramInt1, int paramInt2)
{
if ((paramInt1 == 0) || (paramInt2 == 0))
return;
int i = 32 - paramInt2;
int j = 0;
int k = paramArrayOfInt[j];
int l = j + paramInt1 - 1;
while (j < l)
{
int i1 = k;
k = paramArrayOfInt[(j + 1)];
paramArrayOfInt[j] = (i1 << paramInt2 | k >>> i);
++j;
}
paramArrayOfInt[(paramInt1 - 1)] <<= paramInt2;
}
private static int bitLength(int[] paramArrayOfInt, int paramInt)
{
if (paramInt == 0)
return 0;
return ((paramInt - 1 << 5) + bitLengthForInt(paramArrayOfInt[0]));
}
public BigInteger abs()
{
return ((this.signum >= 0) ? this : negate());
}
public BigInteger negate()
{
return new BigInteger(this.mag, -this.signum);
}
public int signum()
{
return this.signum;
}
public BigInteger mod(BigInteger paramBigInteger)
{
if (paramBigInteger.signum <= 0)
throw new ArithmeticException("BigInteger: modulus not positive");
BigInteger localBigInteger = remainder(paramBigInteger);
return ((localBigInteger.signum >= 0) ? localBigInteger : localBigInteger.add(paramBigInteger));
}
public BigInteger modPow(BigInteger paramBigInteger1, BigInteger paramBigInteger2)
{
if (paramBigInteger2.signum <= 0)
throw new ArithmeticException("BigInteger: modulus not positive");
if (paramBigInteger1.signum == 0)
return ((paramBigInteger2.equals(ONE)) ? ZERO : ONE);
if (equals(ONE))
return ((paramBigInteger2.equals(ONE)) ? ZERO : ONE);
if ((equals(ZERO)) && (paramBigInteger1.signum >= 0))
return ZERO;
if ((equals(negConst[1])) && (!(paramBigInteger1.testBit(0))))
return ((paramBigInteger2.equals(ONE)) ? ZERO : ONE);
int i;
if ((i = (paramBigInteger1.signum < 0) ? 1 : 0) != 0)
paramBigInteger1 = paramBigInteger1.negate();
BigInteger localBigInteger1 = ((this.signum < 0) || (compareTo(paramBigInteger2) >= 0)) ? mod(paramBigInteger2) : this;
BigInteger localBigInteger2;
if (paramBigInteger2.testBit(0))
{
localBigInteger2 = localBigInteger1.oddModPow(paramBigInteger1, paramBigInteger2);
}
else
{
int j = paramBigInteger2.getLowestSetBit();
BigInteger localBigInteger3 = paramBigInteger2.shiftRight(j);
BigInteger localBigInteger4 = ONE.shiftLeft(j);
BigInteger localBigInteger5 = ((this.signum < 0) || (compareTo(localBigInteger3) >= 0)) ? mod(localBigInteger3) : this;
BigInteger localBigInteger6 = (localBigInteger3.equals(ONE)) ? ZERO : localBigInteger5.oddModPow(paramBigInteger1, localBigInteger3);
BigInteger localBigInteger7 = localBigInteger1.modPow2(paramBigInteger1, j);
BigInteger localBigInteger8 = localBigInteger4.modInverse(localBigInteger3);
BigInteger localBigInteger9 = localBigInteger3.modInverse(localBigInteger4);
localBigInteger2 = localBigInteger6.multiply(localBigInteger4).multiply(localBigInteger8).add(localBigInteger7.multiply(localBigInteger3).multiply(localBigInteger9)).mod(paramBigInteger2);
}
return ((i != 0) ? localBigInteger2.modInverse(paramBigInteger2) : localBigInteger2);
}
private BigInteger oddModPow(BigInteger paramBigInteger1, BigInteger paramBigInteger2)
{
if (paramBigInteger1.equals(ONE))
return this;
if (this.signum == 0)
return ZERO;
int[] arrayOfInt1 = (int[])this.mag.clone();
int[] arrayOfInt2 = paramBigInteger1.mag;
int[] arrayOfInt3 = paramBigInteger2.mag;
int i = arrayOfInt3.length;
int j = 0;
int k = bitLength(arrayOfInt2, arrayOfInt2.length);
while ((((k != 17) || (arrayOfInt2[0] != 65537))) && (k > bnExpModThreshTable[j]))
++j;
int l = 1 << j;
int[][] arrayOfInt = new int[l][];
for (int i1 = 0; i1 < l; ++i1)
arrayOfInt[i1] = new int[i];
i1 = -MutableBigInteger.inverseMod32(arrayOfInt3[(i - 1)]);
Object localObject1 = leftShift(arrayOfInt1, arrayOfInt1.length, i << 5);
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger();
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(localObject1);
MutableBigInteger localMutableBigInteger3 = new MutableBigInteger(arrayOfInt3);
MutableBigInteger localMutableBigInteger4 = localMutableBigInteger2.divide(localMutableBigInteger3, localMutableBigInteger1);
arrayOfInt[0] = localMutableBigInteger4.toIntArray();
if (arrayOfInt[0].length < i)
{
int i2 = i - arrayOfInt[0].length;
localObject3 = new int[i];
for (i3 = 0; i3 < arrayOfInt[0].length; ++i3)
localObject3[(i3 + i2)] = arrayOfInt[0][i3];
arrayOfInt[0] = localObject3;
}
Object localObject2 = squareToLen(arrayOfInt[0], i, null);
localObject2 = montReduce(localObject2, arrayOfInt3, i, i1);
Object localObject3 = new int[i];
for (int i3 = 0; i3 < i; ++i3)
localObject3[i3] = localObject2[i3];
for (i3 = 1; i3 < l; ++i3)
{
int[] arrayOfInt4 = multiplyToLen(localObject3, i, arrayOfInt[(i3 - 1)], i, null);
arrayOfInt[i3] = montReduce(arrayOfInt4, arrayOfInt3, i, i1);
}
i3 = 1 << (k - 1 & 0x1F);
int i4 = 0;
int i5 = arrayOfInt2.length;
int i6 = 0;
for (int i7 = 0; i7 <= j; ++i7)
{
i4 = i4 << 1 | (((arrayOfInt2[i6] & i3) != 0) ? 1 : 0);
i3 >>>= 1;
if (i3 != 0)
continue;
++i6;
i3 = -2147483648;
--i5;
}
i7 = k;
--k;
int i8 = 1;
for (i7 = k - j; (i4 & 0x1) == 0; ++i7)
i4 >>>= 1;
[I local[I = arrayOfInt[(i4 >>> 1)];
i4 = 0;
if (i7 == k)
i8 = 0;
while (true)
{
--k;
i4 <<= 1;
if (i5 != 0)
{
i4 |= (((arrayOfInt2[i6] & i3) != 0) ? 1 : 0);
i3 >>>= 1;
if (i3 == 0)
{
++i6;
i3 = -2147483648;
--i5;
}
}
if ((i4 & l) != 0)
{
for (i7 = k - j; (i4 & 0x1) == 0; ++i7)
i4 >>>= 1;
local[I = arrayOfInt[(i4 >>> 1)];
i4 = 0;
}
if (k == i7)
if (i8 != 0)
{
localObject2 = (int[])local[I.clone();
i8 = 0;
}
else
{
localObject3 = localObject2;
localObject1 = multiplyToLen(localObject3, i, local[I, i, localObject1);
localObject1 = montReduce(localObject1, arrayOfInt3, i, i1);
localObject3 = localObject1;
localObject1 = localObject2;
localObject2 = localObject3;
}
if (k == 0)
break;
if (i8 != 0)
continue;
localObject3 = localObject2;
localObject1 = squareToLen(localObject3, i, localObject1);
localObject1 = montReduce(localObject1, arrayOfInt3, i, i1);
localObject3 = localObject1;
localObject1 = localObject2;
localObject2 = localObject3;
}
int[] arrayOfInt5 = new int[2 * i];
for (int i9 = 0; i9 < i; ++i9)
arrayOfInt5[(i9 + i)] = localObject2[i9];
localObject2 = montReduce(arrayOfInt5, arrayOfInt3, i, i1);
arrayOfInt5 = new int[i];
for (i9 = 0; i9 < i; ++i9)
arrayOfInt5[i9] = localObject2[i9];
return ((BigInteger)(BigInteger)(BigInteger)new BigInteger(1, arrayOfInt5));
}
private static int[] montReduce(int[] paramArrayOfInt1, int[] paramArrayOfInt2, int paramInt1, int paramInt2)
{
int i = 0;
int j = paramInt1;
int k = 0;
do
{
int l = paramArrayOfInt1[(paramArrayOfInt1.length - 1 - k)];
int i1 = mulAdd(paramArrayOfInt1, paramArrayOfInt2, k, paramInt1, paramInt2 * l);
i += addOne(paramArrayOfInt1, k, paramInt1, i1);
++k;
}
while (--j > 0);
while (i > 0)
i += subN(paramArrayOfInt1, paramArrayOfInt2, paramInt1);
while (intArrayCmpToLen(paramArrayOfInt1, paramArrayOfInt2, paramInt1) >= 0)
subN(paramArrayOfInt1, paramArrayOfInt2, paramInt1);
return paramArrayOfInt1;
}
private static int intArrayCmpToLen(int[] paramArrayOfInt1, int[] paramArrayOfInt2, int paramInt)
{
for (int i = 0; i < paramInt; ++i)
{
long l1 = paramArrayOfInt1[i] & 0xFFFFFFFF;
long l2 = paramArrayOfInt2[i] & 0xFFFFFFFF;
if (l1 < l2)
return -1;
if (l1 > l2)
return 1;
}
return 0;
}
private static int subN(int[] paramArrayOfInt1, int[] paramArrayOfInt2, int paramInt)
{
long l = 0L;
while (--paramInt >= 0)
{
l = (paramArrayOfInt1[paramInt] & 0xFFFFFFFF) - (paramArrayOfInt2[paramInt] & 0xFFFFFFFF) + (l >> 32);
paramArrayOfInt1[paramInt] = (int)l;
}
return (int)(l >> 32);
}
static int mulAdd(int[] paramArrayOfInt1, int[] paramArrayOfInt2, int paramInt1, int paramInt2, int paramInt3)
{
long l1 = paramInt3 & 0xFFFFFFFF;
long l2 = 0L;
paramInt1 = paramArrayOfInt1.length - paramInt1 - 1;
for (int i = paramInt2 - 1; i >= 0; --i)
{
long l3 = (paramArrayOfInt2[i] & 0xFFFFFFFF) * l1 + (paramArrayOfInt1[paramInt1] & 0xFFFFFFFF) + l2;
paramArrayOfInt1[(paramInt1--)] = (int)l3;
l2 = l3 >>> 32;
}
return (int)l2;
}
static int addOne(int[] paramArrayOfInt, int paramInt1, int paramInt2, int paramInt3)
{
paramInt1 = paramArrayOfInt.length - 1 - paramInt2 - paramInt1;
long l = (paramArrayOfInt[paramInt1] & 0xFFFFFFFF) + (paramInt3 & 0xFFFFFFFF);
paramArrayOfInt[paramInt1] = (int)l;
if (l >>> 32 == 0L)
return 0;
while (--paramInt2 >= 0)
{
if (--paramInt1 < 0)
return 1;
paramArrayOfInt[paramInt1] += 1;
if (paramArrayOfInt[paramInt1] != 0)
return 0;
}
return 1;
}
private BigInteger modPow2(BigInteger paramBigInteger, int paramInt)
{
BigInteger localBigInteger1 = valueOf(1L);
BigInteger localBigInteger2 = mod2(paramInt);
int i = 0;
int j = paramBigInteger.bitLength();
if (testBit(0))
j = (paramInt - 1 < j) ? paramInt - 1 : j;
while (i < j)
{
if (paramBigInteger.testBit(i))
localBigInteger1 = localBigInteger1.multiply(localBigInteger2).mod2(paramInt);
if (++i >= j)
continue;
localBigInteger2 = localBigInteger2.square().mod2(paramInt);
}
return localBigInteger1;
}
private BigInteger mod2(int paramInt)
{
if (bitLength() <= paramInt)
return this;
int i = paramInt + 31 >>> 5;
int[] arrayOfInt = new int[i];
for (int j = 0; j < i; ++j)
arrayOfInt[j] = this.mag[(j + this.mag.length - i)];
j = (i << 5) - paramInt;
int tmp64_63 = 0;
int[] tmp64_62 = arrayOfInt;
tmp64_62[tmp64_63] = (int)(tmp64_62[tmp64_63] & (1L << 32 - j) - 1L);
return new BigInteger(arrayOfInt, 1);
}
public BigInteger modInverse(BigInteger paramBigInteger)
{
if (paramBigInteger.signum != 1)
throw new ArithmeticException("BigInteger: modulus not positive");
if (paramBigInteger.equals(ONE))
return ZERO;
BigInteger localBigInteger = this;
if ((this.signum < 0) || (compareMagnitude(paramBigInteger) >= 0))
localBigInteger = mod(paramBigInteger);
if (localBigInteger.equals(ONE))
return ONE;
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger(localBigInteger);
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(paramBigInteger);
MutableBigInteger localMutableBigInteger3 = localMutableBigInteger1.mutableModInverse(localMutableBigInteger2);
return localMutableBigInteger3.toBigInteger(1);
}
public BigInteger shiftLeft(int paramInt)
{
if (this.signum == 0)
return ZERO;
if (paramInt == 0)
return this;
if (paramInt < 0)
return shiftRight(-paramInt);
int i = paramInt >>> 5;
int j = paramInt & 0x1F;
int k = this.mag.length;
int[] arrayOfInt = null;
int l;
if (j == 0)
{
arrayOfInt = new int[k + i];
for (l = 0; l < k; ++l)
arrayOfInt[l] = this.mag[l];
}
else
{
l = 0;
int i1 = 32 - j;
int i2 = this.mag[0] >>> i1;
if (i2 != 0)
{
arrayOfInt = new int[k + i + 1];
arrayOfInt[(l++)] = i2;
}
else
{
arrayOfInt = new int[k + i];
}
int i3 = 0;
while (i3 < k - 1)
arrayOfInt[(l++)] = (this.mag[(i3++)] << j | this.mag[i3] >>> i1);
arrayOfInt[l] = (this.mag[i3] << j);
}
return new BigInteger(arrayOfInt, this.signum);
}
public BigInteger shiftRight(int paramInt)
{
if (paramInt == 0)
return this;
if (paramInt < 0)
return shiftLeft(-paramInt);
int i = paramInt >>> 5;
int j = paramInt & 0x1F;
int k = this.mag.length;
int[] arrayOfInt = null;
if (i >= k)
return ((this.signum >= 0) ? ZERO : negConst[1]);
int l;
int i1;
int i2;
if (j == 0)
{
l = k - i;
arrayOfInt = new int[l];
for (i1 = 0; i1 < l; ++i1)
arrayOfInt[i1] = this.mag[i1];
}
else
{
l = 0;
i1 = this.mag[0] >>> j;
if (i1 != 0)
{
arrayOfInt = new int[k - i];
arrayOfInt[(l++)] = i1;
}
else
{
arrayOfInt = new int[k - i - 1];
}
i2 = 32 - j;
int i3 = 0;
while (i3 < k - i - 1)
arrayOfInt[(l++)] = (this.mag[(i3++)] << i2 | this.mag[i3] >>> j);
}
if (this.signum < 0)
{
l = 0;
i1 = k - 1;
i2 = k - i;
while ((i1 >= i2) && (l == 0))
{
l = (this.mag[i1] != 0) ? 1 : 0;
--i1;
}
if ((l == 0) && (j != 0))
l = (this.mag[(k - i - 1)] << 32 - j != 0) ? 1 : 0;
if (l != 0)
arrayOfInt = javaIncrement(arrayOfInt);
}
return new BigInteger(arrayOfInt, this.signum);
}
int[] javaIncrement(int[] paramArrayOfInt)
{
// Byte code:
// 0: iconst_0
// 1: istore_2
// 2: aload_1
// 3: arraylength
// 4: iconst_1
// 5: isub
// 6: istore_3
// 7: iload_3
// 8: iflt +22 -> 30
// 11: iload_2
// 12: ifne +18 -> 30
// 15: aload_1
// 16: iload_3
// 17: dup2
// 18: iaload
// 19: iconst_1
// 20: iadd
// 21: dup_x2
// 22: iastore
// 23: istore_2
// 24: iinc 3 255
// 27: goto -20 -> 7
// 30: iload_2
// 31: ifne +14 -> 45
// 34: aload_1
// 35: arraylength
// 36: iconst_1
// 37: iadd
// 38: newarray int
// 40: astore_1
// 41: aload_1
// 42: iconst_0
// 43: iconst_1
// 44: iastore
// 45: aload_1
// 46: areturn
}
public BigInteger and(BigInteger paramBigInteger)
{
int[] arrayOfInt = new int[Math.max(intLength(), paramBigInteger.intLength())];
for (int i = 0; i < arrayOfInt.length; ++i)
arrayOfInt[i] = (getInt(arrayOfInt.length - i - 1) & paramBigInteger.getInt(arrayOfInt.length - i - 1));
return valueOf(arrayOfInt);
}
public BigInteger or(BigInteger paramBigInteger)
{
int[] arrayOfInt = new int[Math.max(intLength(), paramBigInteger.intLength())];
for (int i = 0; i < arrayOfInt.length; ++i)
arrayOfInt[i] = (getInt(arrayOfInt.length - i - 1) | paramBigInteger.getInt(arrayOfInt.length - i - 1));
return valueOf(arrayOfInt);
}
public BigInteger xor(BigInteger paramBigInteger)
{
int[] arrayOfInt = new int[Math.max(intLength(), paramBigInteger.intLength())];
for (int i = 0; i < arrayOfInt.length; ++i)
arrayOfInt[i] = (getInt(arrayOfInt.length - i - 1) ^ paramBigInteger.getInt(arrayOfInt.length - i - 1));
return valueOf(arrayOfInt);
}
public BigInteger not()
{
int[] arrayOfInt = new int[intLength()];
for (int i = 0; i < arrayOfInt.length; ++i)
arrayOfInt[i] = (getInt(arrayOfInt.length - i - 1) ^ 0xFFFFFFFF);
return valueOf(arrayOfInt);
}
public BigInteger andNot(BigInteger paramBigInteger)
{
int[] arrayOfInt = new int[Math.max(intLength(), paramBigInteger.intLength())];
for (int i = 0; i < arrayOfInt.length; ++i)
arrayOfInt[i] = (getInt(arrayOfInt.length - i - 1) & (paramBigInteger.getInt(arrayOfInt.length - i - 1) ^ 0xFFFFFFFF));
return valueOf(arrayOfInt);
}
public boolean testBit(int paramInt)
{
if (paramInt < 0)
throw new ArithmeticException("Negative bit address");
return ((getInt(paramInt >>> 5) & 1 << (paramInt & 0x1F)) != 0);
}
public BigInteger setBit(int paramInt)
{
if (paramInt < 0)
throw new ArithmeticException("Negative bit address");
int i = paramInt >>> 5;
int[] arrayOfInt = new int[Math.max(intLength(), i + 2)];
for (int j = 0; j < arrayOfInt.length; ++j)
arrayOfInt[(arrayOfInt.length - j - 1)] = getInt(j);
arrayOfInt[(arrayOfInt.length - i - 1)] |= 1 << (paramInt & 0x1F);
return valueOf(arrayOfInt);
}
public BigInteger clearBit(int paramInt)
{
if (paramInt < 0)
throw new ArithmeticException("Negative bit address");
int i = paramInt >>> 5;
int[] arrayOfInt = new int[Math.max(intLength(), (paramInt + 1 >>> 5) + 1)];
for (int j = 0; j < arrayOfInt.length; ++j)
arrayOfInt[(arrayOfInt.length - j - 1)] = getInt(j);
arrayOfInt[(arrayOfInt.length - i - 1)] &= (1 << (paramInt & 0x1F) ^ 0xFFFFFFFF);
return valueOf(arrayOfInt);
}
public BigInteger flipBit(int paramInt)
{
if (paramInt < 0)
throw new ArithmeticException("Negative bit address");
int i = paramInt >>> 5;
int[] arrayOfInt = new int[Math.max(intLength(), i + 2)];
for (int j = 0; j < arrayOfInt.length; ++j)
arrayOfInt[(arrayOfInt.length - j - 1)] = getInt(j);
arrayOfInt[(arrayOfInt.length - i - 1)] ^= 1 << (paramInt & 0x1F);
return valueOf(arrayOfInt);
}
public int getLowestSetBit()
{
int i = this.lowestSetBit - 2;
if (i == -2)
{
i = 0;
if (this.signum == 0)
{
--i;
}
else
{
int k;
for (int j = 0; (k = getInt(j)) == 0; ++j);
i += (j << 5) + Integer.numberOfTrailingZeros(k);
}
this.lowestSetBit = (i + 2);
}
return i;
}
public int bitLength()
{
int i = this.bitLength - 1;
if (i == -1)
{
int[] arrayOfInt = this.mag;
int j = arrayOfInt.length;
if (j == 0)
{
i = 0;
}
else
{
int k = (j - 1 << 5) + bitLengthForInt(this.mag[0]);
if (this.signum < 0)
{
int l = (bitCnt(this.mag[0]) == 1) ? 1 : 0;
for (int i1 = 1; (i1 < j) && (l != 0); ++i1)
l = (this.mag[i1] == 0) ? 1 : 0;
i = (l != 0) ? k - 1 : k;
}
else
{
i = k;
}
}
this.bitLength = (i + 1);
}
return i;
}
public int bitCount()
{
int i = this.bitCount - 1;
if (i == -1)
{
i = 0;
for (int j = 0; j < this.mag.length; ++j)
i += bitCnt(this.mag[j]);
if (this.signum < 0)
{
j = 0;
for (int k = this.mag.length - 1; this.mag[k] == 0; --k)
j += 32;
j += Integer.numberOfTrailingZeros(this.mag[k]);
i += j - 1;
}
this.bitCount = (i + 1);
}
return i;
}
static int bitCnt(int paramInt)
{
paramInt -= ((0xAAAAAAAA & paramInt) >>> 1);
paramInt = (paramInt & 0x33333333) + (paramInt >>> 2 & 0x33333333);
paramInt = paramInt + (paramInt >>> 4) & 0xF0F0F0F;
paramInt += (paramInt >>> 8);
paramInt += (paramInt >>> 16);
return (paramInt & 0xFF);
}
public boolean isProbablePrime(int paramInt)
{
if (paramInt <= 0)
return true;
BigInteger localBigInteger = abs();
if (localBigInteger.equals(TWO))
return true;
if ((!(localBigInteger.testBit(0))) || (localBigInteger.equals(ONE)))
return false;
return localBigInteger.primeToCertainty(paramInt, null);
}
public int compareTo(BigInteger paramBigInteger)
{
if (this.signum == paramBigInteger.signum)
{
switch (this.signum)
{
case 1:
return compareMagnitude(paramBigInteger);
case -1:
return paramBigInteger.compareMagnitude(this);
}
return 0;
}
return ((this.signum > paramBigInteger.signum) ? 1 : -1);
}
final int compareMagnitude(BigInteger paramBigInteger)
{
int[] arrayOfInt1 = this.mag;
int i = arrayOfInt1.length;
int[] arrayOfInt2 = paramBigInteger.mag;
int j = arrayOfInt2.length;
if (i < j)
return -1;
if (i > j)
return 1;
for (int k = 0; k < i; ++k)
{
int l = arrayOfInt1[k];
int i1 = arrayOfInt2[k];
if (l != i1)
return (((l & 0xFFFFFFFF) < (i1 & 0xFFFFFFFF)) ? -1 : 1);
}
return 0;
}
public boolean equals(Object paramObject)
{
if (paramObject == this)
return true;
if (!(paramObject instanceof BigInteger))
return false;
BigInteger localBigInteger = (BigInteger)paramObject;
if (localBigInteger.signum != this.signum)
return false;
int[] arrayOfInt1 = this.mag;
int i = arrayOfInt1.length;
int[] arrayOfInt2 = localBigInteger.mag;
if (arrayOfInt2.length != i)
return false;
for (int j = 0; j < i; ++j)
if (arrayOfInt2[j] != arrayOfInt1[j])
return false;
return true;
}
public BigInteger min(BigInteger paramBigInteger)
{
return ((compareTo(paramBigInteger) < 0) ? this : paramBigInteger);
}
public BigInteger max(BigInteger paramBigInteger)
{
return ((compareTo(paramBigInteger) > 0) ? this : paramBigInteger);
}
public int hashCode()
{
int i = 0;
for (int j = 0; j < this.mag.length; ++j)
i = (int)(31 * i + (this.mag[j] & 0xFFFFFFFF));
return (i * this.signum);
}
public String toString(int paramInt)
{
if (this.signum == 0)
return "0";
if ((paramInt < 2) || (paramInt > 36))
paramInt = 10;
int i = (4 * this.mag.length + 6) / 7;
String[] arrayOfString = new String[i];
Object localObject1 = abs();
int j = 0;
while (((BigInteger)localObject1).signum != 0)
{
localObject2 = longRadix[paramInt];
MutableBigInteger localMutableBigInteger1 = new MutableBigInteger();
MutableBigInteger localMutableBigInteger2 = new MutableBigInteger(((BigInteger)localObject1).mag);
MutableBigInteger localMutableBigInteger3 = new MutableBigInteger(((BigInteger)localObject2).mag);
MutableBigInteger localMutableBigInteger4 = localMutableBigInteger2.divide(localMutableBigInteger3, localMutableBigInteger1);
BigInteger localBigInteger1 = localMutableBigInteger1.toBigInteger(((BigInteger)localObject1).signum * ((BigInteger)localObject2).signum);
BigInteger localBigInteger2 = localMutableBigInteger4.toBigInteger(((BigInteger)localObject1).signum * ((BigInteger)localObject2).signum);
arrayOfString[(j++)] = Long.toString(localBigInteger2.longValue(), paramInt);
localObject1 = localBigInteger1;
}
Object localObject2 = new StringBuilder(j * digitsPerLong[paramInt] + 1);
if (this.signum < 0)
((StringBuilder)localObject2).append('-');
((StringBuilder)localObject2).append(arrayOfString[(j - 1)]);
for (int k = j - 2; k >= 0; --k)
{
int l = digitsPerLong[paramInt] - arrayOfString[k].length();
if (l != 0)
((StringBuilder)localObject2).append(zeros[l]);
((StringBuilder)localObject2).append(arrayOfString[k]);
}
return ((String)(String)((StringBuilder)localObject2).toString());
}
public String toString()
{
return toString(10);
}
public byte[] toByteArray()
{
int i = bitLength() / 8 + 1;
byte[] arrayOfByte = new byte[i];
int j = i - 1;
int k = 4;
int l = 0;
int i1 = 0;
while (j >= 0)
{
if (k == 4)
{
l = getInt(i1++);
k = 1;
}
else
{
l >>>= 8;
++k;
}
arrayOfByte[j] = (byte)l;
--j;
}
return arrayOfByte;
}
public int intValue()
{
int i = 0;
i = getInt(0);
return i;
}
public long longValue()
{
long l = 0L;
for (int i = 1; i >= 0; --i)
l = (l << 32) + (getInt(i) & 0xFFFFFFFF);
return l;
}
public float floatValue()
{
return Float.parseFloat(toString());
}
public double doubleValue()
{
return Double.parseDouble(toString());
}
private static int[] stripLeadingZeroInts(int[] paramArrayOfInt)
{
int i = paramArrayOfInt.length;
for (int j = 0; (j < i) && (paramArrayOfInt[j] == 0); ++j);
return Arrays.copyOfRange(paramArrayOfInt, j, i);
}
private static int[] trustedStripLeadingZeroInts(int[] paramArrayOfInt)
{
int i = paramArrayOfInt.length;
for (int j = 0; (j < i) && (paramArrayOfInt[j] == 0); ++j);
return ((j == 0) ? paramArrayOfInt : Arrays.copyOfRange(paramArrayOfInt, j, i));
}
private static int[] stripLeadingZeroBytes(byte[] paramArrayOfByte)
{
int i = paramArrayOfByte.length;
for (int j = 0; (j < i) && (paramArrayOfByte[j] == 0); ++j);
int k = i - j + 3 >>> 2;
int[] arrayOfInt = new int[k];
int l = i - 1;
for (int i1 = k - 1; i1 >= 0; --i1)
{
arrayOfInt[i1] = (paramArrayOfByte[(l--)] & 0xFF);
int i2 = l - j + 1;
int i3 = Math.min(3, i2);
for (int i4 = 8; i4 <= i3 << 3; i4 += 8)
arrayOfInt[i1] |= (paramArrayOfByte[(l--)] & 0xFF) << i4;
}
return arrayOfInt;
}
private static int[] makePositive(byte[] paramArrayOfByte)
{
int k = paramArrayOfByte.length;
for (int i = 0; (i < k) && (paramArrayOfByte[i] == -1); ++i);
for (int j = i; (j < k) && (paramArrayOfByte[j] == 0); ++j);
int l = (j == k) ? 1 : 0;
int i1 = (k - i + l + 3) / 4;
int[] arrayOfInt = new int[i1];
int i2 = k - 1;
for (int i3 = i1 - 1; i3 >= 0; --i3)
{
arrayOfInt[i3] = (paramArrayOfByte[(i2--)] & 0xFF);
int i4 = Math.min(3, i2 - i + 1);
if (i4 < 0)
i4 = 0;
for (int i5 = 8; i5 <= 8 * i4; i5 += 8)
arrayOfInt[i3] |= (paramArrayOfByte[(i2--)] & 0xFF) << i5;
i5 = -1 >>> 8 * (3 - i4);
arrayOfInt[i3] = ((arrayOfInt[i3] ^ 0xFFFFFFFF) & i5);
}
for (i3 = arrayOfInt.length - 1; i3 >= 0; --i3)
{
arrayOfInt[i3] = (int)((arrayOfInt[i3] & 0xFFFFFFFF) + 1L);
if (arrayOfInt[i3] != 0)
break;
}
return arrayOfInt;
}
private static int[] makePositive(int[] paramArrayOfInt)
{
for (int i = 0; (i < paramArrayOfInt.length) && (paramArrayOfInt[i] == -1); ++i);
for (int j = i; (j < paramArrayOfInt.length) && (paramArrayOfInt[j] == 0); ++j);
int k = (j == paramArrayOfInt.length) ? 1 : 0;
int[] arrayOfInt = new int[paramArrayOfInt.length - i + k];
for (int l = i; l < paramArrayOfInt.length; ++l)
arrayOfInt[(l - i + k)] = (paramArrayOfInt[l] ^ 0xFFFFFFFF);
for (l = arrayOfInt.length - 1; ; --l)
if (arrayOfInt[l] += 1 != 0)
break;
return arrayOfInt;
}
private int intLength()
{
return ((bitLength() >>> 5) + 1);
}
private int signBit()
{
return ((this.signum < 0) ? 1 : 0);
}
private int signInt()
{
return ((this.signum < 0) ? -1 : 0);
}
private int getInt(int paramInt)
{
if (paramInt < 0)
return 0;
if (paramInt >= this.mag.length)
return signInt();
int i = this.mag[(this.mag.length - paramInt - 1)];
return ((paramInt <= firstNonzeroIntNum()) ? -i : (this.signum >= 0) ? i : i ^ 0xFFFFFFFF);
}
private int firstNonzeroIntNum()
{
int i = this.firstNonzeroIntNum - 2;
if (i == -2)
{
i = 0;
for (int j = this.mag.length - 1; (j >= 0) && (this.mag[j] == 0); --j);
i = this.mag.length - j - 1;
this.firstNonzeroIntNum = (i + 2);
}
return i;
}
private void readObject(ObjectInputStream paramObjectInputStream)
throws IOException, ClassNotFoundException
{
ObjectInputStream.GetField localGetField = paramObjectInputStream.readFields();
int i = localGetField.get("signum", -2);
byte[] arrayOfByte = (byte[])(byte[])localGetField.get("magnitude", null);
String str;
if ((i < -1) || (i > 1))
{
str = "BigInteger: Invalid signum value";
if (localGetField.defaulted("signum"))
str = "BigInteger: Signum not present in stream";
throw new StreamCorruptedException(str);
}
if (((arrayOfByte.length == 0) ? 1 : 0) != ((i == 0) ? 1 : 0))
{
str = "BigInteger: signum-magnitude mismatch";
if (localGetField.defaulted("magnitude"))
str = "BigInteger: Magnitude not present in stream";
throw new StreamCorruptedException(str);
}
unsafe.putIntVolatile(this, signumOffset, i);
unsafe.putObjectVolatile(this, magOffset, stripLeadingZeroBytes(arrayOfByte));
}
private void writeObject(ObjectOutputStream paramObjectOutputStream)
throws IOException
{
ObjectOutputStream.PutField localPutField = paramObjectOutputStream.putFields();
localPutField.put("signum", this.signum);
localPutField.put("magnitude", magSerializedForm());
localPutField.put("bitCount", -1);
localPutField.put("bitLength", -1);
localPutField.put("lowestSetBit", -2);
localPutField.put("firstNonzeroByteNum", -2);
paramObjectOutputStream.writeFields();
}
private byte[] magSerializedForm()
{
int i = this.mag.length;
int j = (i == 0) ? 0 : (i - 1 << 5) + bitLengthForInt(this.mag[0]);
int k = (j + 7) / 8;
byte[] arrayOfByte = new byte[k];
int l = k - 1;
int i1 = 4;
int i2 = i - 1;
int i3 = 0;
while (l >= 0)
{
if (i1 == 4)
{
i3 = this.mag[(i2--)];
i1 = 1;
}
else
{
i3 >>>= 8;
++i1;
}
arrayOfByte[l] = (byte)i3;
--l;
}
return arrayOfByte;
}
static
{
bitsPerDigit = new long[] { 0L, 0L, 1024L, 1624L, 2048L, 2378L, 2648L, 2875L, 3072L, 3247L, 3402L, 3543L, 3672L, 3790L, 3899L, 4001L, 4096L, 4186L, 4271L, 4350L, 4426L, 4498L, 4567L, 4633L, 4696L, 4756L, 4814L, 4870L, 4923L, 4975L, 5025L, 5074L, 5120L, 5166L, 5210L, 5253L, 5295L };
SMALL_PRIME_PRODUCT = valueOf(152125131763605L);
posConst = new BigInteger[17];
negConst = new BigInteger[17];
for (int i = 1; i <= 16; ++i)
{
int[] arrayOfInt = new int[1];
arrayOfInt[0] = i;
posConst[i] = new BigInteger(arrayOfInt, 1);
negConst[i] = new BigInteger(arrayOfInt, -1);
}
ZERO = new BigInteger(new int[0], 0);
ONE = valueOf(1L);
TWO = valueOf(2L);
TEN = valueOf(10L);
bnExpModThreshTable = new int[] { 7, 25, 81, 241, 673, 1793, 2147483647 };
zeros = new String[64];
zeros[63] = "000000000000000000000000000000000000000000000000000000000000000";
for (i = 0; i < 63; ++i)
zeros[i] = zeros[63].substring(0, i);
digitsPerLong = new int[] { 0, 0, 62, 39, 31, 27, 24, 22, 20, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12 };
longRadix = new BigInteger[] { null, null, valueOf(4611686018427387904L), valueOf(4052555153018976267L), valueOf(4611686018427387904L), valueOf(7450580596923828125L), valueOf(4738381338321616896L), valueOf(3909821048582988049L), valueOf(1152921504606846976L), valueOf(1350851717672992089L), valueOf(1000000000000000000L), valueOf(5559917313492231481L), valueOf(2218611106740436992L), valueOf(8650415919381337933L), valueOf(2177953337809371136L), valueOf(6568408355712890625L), valueOf(1152921504606846976L), valueOf(2862423051509815793L), valueOf(6746640616477458432L), valueOf(799006685782884121L), valueOf(1638400000000000000L), valueOf(3243919932521508681L), valueOf(6221821273427820544L), valueOf(504036361936467383L), valueOf(876488338465357824L), valueOf(1490116119384765625L), valueOf(2481152873203736576L), valueOf(4052555153018976267L), valueOf(6502111422497947648L), valueOf(353814783205469041L), valueOf(531441000000000000L), valueOf(787662783788549761L), valueOf(1152921504606846976L), valueOf(1667889514952984961L), valueOf(2386420683693101056L), valueOf(3379220508056640625L), valueOf(4738381338321616896L) };
digitsPerInt = new int[] { 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 };
intRadix = new int[] { 0, 0, 1073741824, 1162261467, 1073741824, 1220703125, 362797056, 1977326743, 1073741824, 387420489, 1000000000, 214358881, 429981696, 815730721, 1475789056, 170859375, 268435456, 410338673, 612220032, 893871739, 1280000000, 1801088541, 113379904, 148035889, 191102976, 244140625, 308915776, 387420489, 481890304, 594823321, 729000000, 887503681, 1073741824, 1291467969, 1544804416, 1838265625, 60466176 };
serialPersistentFields = new ObjectStreamField[] { new ObjectStreamField("signum", Integer.TYPE), new ObjectStreamField("magnitude", [B.class), new ObjectStreamField("bitCount", Integer.TYPE), new ObjectStreamField("bitLength", Integer.TYPE), new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE), new ObjectStreamField("lowestSetBit", Integer.TYPE) };
unsafe = Unsafe.getUnsafe();
try
{
signumOffset = unsafe.objectFieldOffset(BigInteger.class.getDeclaredField("signum"));
magOffset = unsafe.objectFieldOffset(BigInteger.class.getDeclaredField("mag"));
}
catch (Exception localException)
{
throw new Error(localException);
}
}
}