package ser.androidbitset; // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // import java.security.SecureRandom; import java.util.Arrays; import java.util.Random; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.StreamCorruptedException; import sun.misc.Unsafe; public class JDKBigInt extends Number implements Comparable<JDKBigInt> { final int signum; final int[] mag; /** @deprecated */ @Deprecated private int bitCount; /** @deprecated */ @Deprecated private int bitLength; /** @deprecated */ @Deprecated private int lowestSetBit; /** @deprecated */ @Deprecated private int firstNonzeroIntNum; static final long LONG_MASK = 4294967295L; private static long[] 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}; private static final int SMALL_PRIME_THRESHOLD = 95; private static final int DEFAULT_PRIME_CERTAINTY = 100; private static final JDKBigInt SMALL_PRIME_PRODUCT = valueOf(152125131763605L); private static volatile Random staticRandom; private static final int MAX_CONSTANT = 16; private static JDKBigInt[] posConst = new JDKBigInt[17]; private static JDKBigInt[] negConst = new JDKBigInt[17]; public static final JDKBigInt ZERO; public static final JDKBigInt ONE; private static final JDKBigInt TWO; public static final JDKBigInt TEN; static int[] bnExpModThreshTable; private static String[] zeros; private static int[] digitsPerLong; private static JDKBigInt[] 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 JDKBigInt(byte[] val) { if(val.length == 0) { throw new NumberFormatException("Zero length JDKBigInt"); } else { if(val[0] < 0) { this.mag = makePositive((byte[])val); this.signum = -1; } else { this.mag = stripLeadingZeroBytes(val); this.signum = this.mag.length == 0?0:1; } } } private JDKBigInt(int[] val) { if(val.length == 0) { throw new NumberFormatException("Zero length JDKBigInt"); } else { if(val[0] < 0) { this.mag = makePositive((int[])val); this.signum = -1; } else { this.mag = trustedStripLeadingZeroInts(val); this.signum = this.mag.length == 0?0:1; } } } public JDKBigInt(int signum, byte[] magnitude) { this.mag = stripLeadingZeroBytes(magnitude); if(signum >= -1 && signum <= 1) { if(this.mag.length == 0) { this.signum = 0; } else { if(signum == 0) { throw new NumberFormatException("signum-magnitude mismatch"); } this.signum = signum; } } else { throw new NumberFormatException("Invalid signum value"); } } private JDKBigInt(int signum, int[] magnitude) { this.mag = stripLeadingZeroInts(magnitude); if(signum >= -1 && signum <= 1) { if(this.mag.length == 0) { this.signum = 0; } else { if(signum == 0) { throw new NumberFormatException("signum-magnitude mismatch"); } this.signum = signum; } } else { throw new NumberFormatException("Invalid signum value"); } } public JDKBigInt(String val, int radix) { int cursor = 0; int len = val.length(); if(radix >= 2 && radix <= 36) { if(len == 0) { throw new NumberFormatException("Zero length JDKBigInt"); } else { byte sign = 1; int index1 = val.lastIndexOf(45); int index2 = val.lastIndexOf(43); if(index1 + index2 > -1) { throw new NumberFormatException("Illegal embedded sign character"); } else { if(index1 == 0 || index2 == 0) { cursor = 1; if(len == 1) { throw new NumberFormatException("Zero length JDKBigInt"); } } if(index1 == 0) { sign = -1; } while(cursor < len && Character.digit(val.charAt(cursor), radix) == 0) { ++cursor; } if(cursor == len) { this.signum = 0; this.mag = ZERO.mag; } else { int numDigits = len - cursor; this.signum = sign; int numBits = (int)(((long)numDigits * bitsPerDigit[radix] >>> 10) + 1L); int numWords = numBits + 31 >>> 5; int[] magnitude = new int[numWords]; 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"); } else { int superRadix = intRadix[radix]; boolean groupVal = false; while(cursor < len) { group = val.substring(cursor, cursor += digitsPerInt[radix]); int var16 = Integer.parseInt(group, radix); if(var16 < 0) { throw new NumberFormatException("Illegal digit"); } destructiveMulAdd(magnitude, superRadix, var16); } this.mag = trustedStripLeadingZeroInts(magnitude); } } } } } else { throw new NumberFormatException("Radix out of range"); } } JDKBigInt(char[] val) { int cursor = 0; int len = val.length; byte sign = 1; if(val[0] == 45) { if(len == 1) { throw new NumberFormatException("Zero length JDKBigInt"); } sign = -1; cursor = 1; } else if(val[0] == 43) { if(len == 1) { throw new NumberFormatException("Zero length JDKBigInt"); } cursor = 1; } while(cursor < len && Character.digit(val[cursor], 10) == 0) { ++cursor; } if(cursor == len) { this.signum = 0; this.mag = ZERO.mag; } else { int numDigits = len - cursor; this.signum = sign; int numWords; if(len < 10) { numWords = 1; } else { int magnitude = (int)(((long)numDigits * bitsPerDigit[10] >>> 10) + 1L); numWords = magnitude + 31 >>> 5; } int[] var10 = new int[numWords]; int firstGroupLen = numDigits % digitsPerInt[10]; if(firstGroupLen == 0) { firstGroupLen = digitsPerInt[10]; } var10[numWords - 1] = this.parseInt(val, cursor, cursor += firstGroupLen); while(cursor < len) { int groupVal = this.parseInt(val, cursor, cursor += digitsPerInt[10]); destructiveMulAdd(var10, intRadix[10], groupVal); } this.mag = trustedStripLeadingZeroInts(var10); } } private int parseInt(char[] source, int start, int end) { int result = Character.digit(source[start++], 10); if(result == -1) { throw new NumberFormatException(new String(source)); } else { for(int index = start; index < end; ++index) { int nextVal = Character.digit(source[index], 10); if(nextVal == -1) { throw new NumberFormatException(new String(source)); } result = 10 * result + nextVal; } return result; } } private static void destructiveMulAdd(int[] x, int y, int z) { long ylong = (long)y & 4294967295L; long zlong = (long)z & 4294967295L; int len = x.length; long product = 0L; long carry = 0L; for(int sum = len - 1; sum >= 0; --sum) { product = ylong * ((long)x[sum] & 4294967295L) + carry; x[sum] = (int)product; carry = product >>> 32; } long var15 = ((long)x[len - 1] & 4294967295L) + zlong; x[len - 1] = (int)var15; carry = var15 >>> 32; for(int i = len - 2; i >= 0; --i) { var15 = ((long)x[i] & 4294967295L) + carry; x[i] = (int)var15; carry = var15 >>> 32; } } public JDKBigInt(String val) { this((String)val, 10); } public JDKBigInt(int numBits, Random rnd) { this(1, (byte[])randomBits(numBits, rnd)); } private static byte[] randomBits(int numBits, Random rnd) { if(numBits < 0) { throw new IllegalArgumentException("numBits must be non-negative"); } else { int numBytes = (int)(((long)numBits + 7L) / 8L); byte[] randomBits = new byte[numBytes]; if(numBytes > 0) { rnd.nextBytes(randomBits); int excessBits = 8 * numBytes - numBits; randomBits[0] = (byte)(randomBits[0] & (1 << 8 - excessBits) - 1); } return randomBits; } } private boolean passesLucasLehmer() { JDKBigInt thisPlusOne = this.add(ONE); int d; for(d = 5; jacobiSymbol(d, this) != -1; d = d < 0?Math.abs(d) + 2:-(d + 2)) { ; } JDKBigInt u = lucasLehmerSequence(d, thisPlusOne, this); return u.mod(this).equals(ZERO); } private static int jacobiSymbol(int p, JDKBigInt n) { if(p == 0) { return 0; } else { int j = 1; int u = n.mag[n.mag.length - 1]; int t; if(p < 0) { p = -p; t = u & 7; if(t == 3 || t == 7) { j = -j; } } while((p & 3) == 0) { p >>= 2; } if((p & 1) == 0) { p >>= 1; if(((u ^ u >> 1) & 2) != 0) { j = -j; } } if(p == 1) { return j; } else { if((p & u & 2) != 0) { j = -j; } for(u = n.mod(valueOf((long)p)).intValue(); u != 0; u %= t) { while((u & 3) == 0) { u >>= 2; } if((u & 1) == 0) { u >>= 1; if(((p ^ p >> 1) & 2) != 0) { j = -j; } } if(u == 1) { return j; } assert u < p; t = u; u = p; p = t; if((u & t & 2) != 0) { j = -j; } } return 0; } } } private static JDKBigInt lucasLehmerSequence(int z, JDKBigInt k, JDKBigInt n) { JDKBigInt d = valueOf((long)z); JDKBigInt u = ONE; JDKBigInt v = ONE; for(int i = k.bitLength() - 2; i >= 0; --i) { JDKBigInt u2 = u.multiply(v).mod(n); JDKBigInt v2 = v.square().add(d.multiply(u.square())).mod(n); if(v2.testBit(0)) { v2 = v2.subtract(n); } v2 = v2.shiftRight(1); u = u2; v = v2; if(k.testBit(i)) { u2 = u2.add(v2).mod(n); if(u2.testBit(0)) { u2 = u2.subtract(n); } u2 = u2.shiftRight(1); v2 = v2.add(d.multiply(u)).mod(n); if(v2.testBit(0)) { v2 = v2.subtract(n); } v2 = v2.shiftRight(1); u = u2; v = v2; } } return u; } private static Random getSecureRandom() { if(staticRandom == null) { staticRandom = new SecureRandom(); } return staticRandom; } JDKBigInt(int[] magnitude, int signum) { this.signum = magnitude.length == 0?0:signum; this.mag = magnitude; } private JDKBigInt(byte[] magnitude, int signum) { this.signum = magnitude.length == 0?0:signum; this.mag = stripLeadingZeroBytes(magnitude); } public static JDKBigInt valueOf(long val) { return val == 0L?ZERO:(val > 0L && val <= 16L?posConst[(int)val]:(val < 0L && val >= -16L?negConst[(int)(-val)]:new JDKBigInt(val))); } private JDKBigInt(long val) { if(val < 0L) { val = -val; this.signum = -1; } else { this.signum = 1; } int highWord = (int)(val >>> 32); if(highWord == 0) { this.mag = new int[1]; this.mag[0] = (int)val; } else { this.mag = new int[2]; this.mag[0] = highWord; this.mag[1] = (int)val; } } private static JDKBigInt valueOf(int[] val) { return val[0] > 0?new JDKBigInt(val, 1):new JDKBigInt(val); } public JDKBigInt add(JDKBigInt val) { if(val.signum == 0) { return this; } else if(this.signum == 0) { return val; } else if(val.signum == this.signum) { return new JDKBigInt(add(this.mag, val.mag), this.signum); } else { int cmp = this.compareMagnitude(val); if(cmp == 0) { return ZERO; } else { int[] resultMag = cmp > 0?subtract(this.mag, val.mag):subtract(val.mag, this.mag); resultMag = trustedStripLeadingZeroInts(resultMag); return new JDKBigInt(resultMag, cmp == this.signum?1:-1); } } } private static int[] add(int[] x, int[] y) { if(x.length < y.length) { int[] xIndex = x; x = y; y = xIndex; } int var9 = x.length; int yIndex = y.length; int[] result = new int[var9]; long sum; for(sum = 0L; yIndex > 0; result[var9] = (int)sum) { --var9; long var10000 = (long)x[var9] & 4294967295L; --yIndex; sum = var10000 + ((long)y[yIndex] & 4294967295L) + (sum >>> 32); } boolean carry; for(carry = sum >>> 32 != 0L; var9 > 0 && carry; carry = (result[var9] = x[var9] + 1) == 0) { --var9; } while(var9 > 0) { --var9; result[var9] = x[var9]; } if(carry) { int[] bigger = new int[result.length + 1]; System.arraycopy(result, 0, bigger, 1, result.length); bigger[0] = 1; return bigger; } else { return result; } } public JDKBigInt subtract(JDKBigInt val) { if(val.signum == 0) { return this; } else if(this.signum == 0) { return val.negate(); } else if(val.signum != this.signum) { return new JDKBigInt(add(this.mag, val.mag), this.signum); } else { int cmp = this.compareMagnitude(val); if(cmp == 0) { return ZERO; } else { int[] resultMag = cmp > 0?subtract(this.mag, val.mag):subtract(val.mag, this.mag); resultMag = trustedStripLeadingZeroInts(resultMag); return new JDKBigInt(resultMag, cmp == this.signum?1:-1); } } } private static int[] subtract(int[] big, int[] little) { int bigIndex = big.length; int[] result = new int[bigIndex]; int littleIndex = little.length; long difference; for(difference = 0L; littleIndex > 0; result[bigIndex] = (int)difference) { --bigIndex; long var10000 = (long)big[bigIndex] & 4294967295L; --littleIndex; difference = var10000 - ((long)little[littleIndex] & 4294967295L) + (difference >> 32); } for(boolean borrow = difference >> 32 != 0L; bigIndex > 0 && borrow; borrow = (result[bigIndex] = big[bigIndex] - 1) == -1) { --bigIndex; } while(bigIndex > 0) { --bigIndex; result[bigIndex] = big[bigIndex]; } return result; } public JDKBigInt multiply(JDKBigInt val) { if(val.signum != 0 && this.signum != 0) { int[] result = this.multiplyToLen(this.mag, this.mag.length, val.mag, val.mag.length, (int[])null); result = trustedStripLeadingZeroInts(result); return new JDKBigInt(result, this.signum == val.signum?1:-1); } else { return ZERO; } } JDKBigInt multiply(long v) { if(v != 0L && this.signum != 0) { if(v == -9223372036854775808L) { return this.multiply(valueOf(v)); } else { int rsign = v > 0L?this.signum:-this.signum; if(v < 0L) { v = -v; } long dh = v >>> 32; long dl = v & 4294967295L; int xlen = this.mag.length; int[] value = this.mag; int[] rmag = dh == 0L?new int[xlen + 1]:new int[xlen + 2]; long carry = 0L; int rstart = rmag.length - 1; int i; long product; for(i = xlen - 1; i >= 0; --i) { product = ((long)value[i] & 4294967295L) * dl + carry; rmag[rstart--] = (int)product; carry = product >>> 32; } rmag[rstart] = (int)carry; if(dh != 0L) { carry = 0L; rstart = rmag.length - 2; for(i = xlen - 1; i >= 0; --i) { product = ((long)value[i] & 4294967295L) * dh + ((long)rmag[rstart] & 4294967295L) + carry; rmag[rstart--] = (int)product; carry = product >>> 32; } rmag[0] = (int)carry; } if(carry == 0L) { rmag = Arrays.copyOfRange(rmag, 1, rmag.length); } return new JDKBigInt(rmag, rsign); } } else { return ZERO; } } private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) { int xstart = xlen - 1; int ystart = ylen - 1; if(z == null || z.length < xlen + ylen) { z = new int[xlen + ylen]; } long carry = 0L; int i = ystart; int j; for(j = ystart + 1 + xstart; i >= 0; --j) { long k = ((long)y[i] & 4294967295L) * ((long)x[xstart] & 4294967295L) + carry; z[j] = (int)k; carry = k >>> 32; --i; } z[xstart] = (int)carry; for(i = xstart - 1; i >= 0; --i) { carry = 0L; j = ystart; for(int var15 = ystart + 1 + i; j >= 0; --var15) { long product = ((long)y[j] & 4294967295L) * ((long)x[i] & 4294967295L) + ((long)z[var15] & 4294967295L) + carry; z[var15] = (int)product; carry = product >>> 32; --j; } z[i] = (int)carry; } return z; } private JDKBigInt square() { if(this.signum == 0) { return ZERO; } else { int[] z = squareToLen(this.mag, this.mag.length, (int[])null); return new JDKBigInt(trustedStripLeadingZeroInts(z), 1); } } private static final int[] squareToLen(int[] x, int len, int[] z) { int zlen = len << 1; if(z == null || z.length < zlen) { z = new int[zlen]; } int lastProductLowWord = 0; int i = 0; int offset; for(offset = 0; i < len; ++i) { long t = (long)x[i] & 4294967295L; long product = t * t; z[offset++] = lastProductLowWord << 31 | (int)(product >>> 33); z[offset++] = (int)(product >>> 1); lastProductLowWord = (int)product; } i = len; for(offset = 1; i > 0; offset += 2) { int var11 = x[i - 1]; var11 = mulAdd(z, x, offset, i - 1, var11); addOne(z, offset - 1, i, var11); --i; } primitiveLeftShift(z, zlen, 1); z[zlen - 1] |= x[len - 1] & 1; return z; } public JDKBigInt pow(int exponent) { if(exponent < 0) { throw new ArithmeticException("Negative exponent"); } else if(this.signum == 0) { return exponent == 0?ONE:this; } else { int newSign = this.signum < 0 && (exponent & 1) == 1?-1:1; int[] baseToPow2 = this.mag; int[] result = new int[]{1}; while(exponent != 0) { if((exponent & 1) == 1) { result = this.multiplyToLen(result, result.length, baseToPow2, baseToPow2.length, (int[])null); result = trustedStripLeadingZeroInts(result); } if((exponent >>>= 1) != 0) { baseToPow2 = squareToLen(baseToPow2, baseToPow2.length, (int[])null); baseToPow2 = trustedStripLeadingZeroInts(baseToPow2); } } return new JDKBigInt(result, newSign); } } static int bitLengthForInt(int n) { return 32 - Integer.numberOfLeadingZeros(n); } private static int[] leftShift(int[] a, int len, int n) { int nInts = n >>> 5; int nBits = n & 31; int bitsInHighWord = bitLengthForInt(a[0]); if(n <= 32 - bitsInHighWord) { primitiveLeftShift(a, len, nBits); return a; } else { int[] result; int i; if(nBits <= 32 - bitsInHighWord) { result = new int[nInts + len]; for(i = 0; i < len; ++i) { result[i] = a[i]; } primitiveLeftShift(result, result.length, nBits); return result; } else { result = new int[nInts + len + 1]; for(i = 0; i < len; ++i) { result[i] = a[i]; } primitiveRightShift(result, result.length, 32 - nBits); return result; } } } static void primitiveRightShift(int[] a, int len, int n) { int n2 = 32 - n; int i = len - 1; for(int c = a[i]; i > 0; --i) { int b = c; c = a[i - 1]; a[i] = c << n2 | b >>> n; } a[0] >>>= n; } static void primitiveLeftShift(int[] a, int len, int n) { if(len != 0 && n != 0) { int n2 = 32 - n; int i = 0; int c = a[i]; for(int m = i + len - 1; i < m; ++i) { int b = c; c = a[i + 1]; a[i] = b << n | c >>> n2; } a[len - 1] <<= n; } } private static int bitLength(int[] val, int len) { return len == 0?0:(len - 1 << 5) + bitLengthForInt(val[0]); } public JDKBigInt abs() { return this.signum >= 0?this:this.negate(); } public JDKBigInt negate() { return new JDKBigInt(this.mag, -this.signum); } public int signum() { return this.signum; } public JDKBigInt mod(JDKBigInt m) { return new JDKBigInt(0); } private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) { int c = 0; int len = mlen; int offset = 0; do { int nEnd = n[n.length - 1 - offset]; int carry = mulAdd(n, mod, offset, mlen, inv * nEnd); c += addOne(n, offset, mlen, carry); ++offset; --len; } while(len > 0); while(c > 0) { c += subN(n, mod, mlen); } while(intArrayCmpToLen(n, mod, mlen) >= 0) { subN(n, mod, mlen); } return n; } private static int intArrayCmpToLen(int[] arg1, int[] arg2, int len) { for(int i = 0; i < len; ++i) { long b1 = (long)arg1[i] & 4294967295L; long b2 = (long)arg2[i] & 4294967295L; if(b1 < b2) { return -1; } if(b1 > b2) { return 1; } } return 0; } private static int subN(int[] a, int[] b, int len) { long sum = 0L; while(true) { --len; if(len < 0) { return (int)(sum >> 32); } sum = ((long)a[len] & 4294967295L) - ((long)b[len] & 4294967295L) + (sum >> 32); a[len] = (int)sum; } } static int mulAdd(int[] out, int[] in, int offset, int len, int k) { long kLong = (long)k & 4294967295L; long carry = 0L; offset = out.length - offset - 1; for(int j = len - 1; j >= 0; --j) { long product = ((long)in[j] & 4294967295L) * kLong + ((long)out[offset] & 4294967295L) + carry; out[offset--] = (int)product; carry = product >>> 32; } return (int)carry; } static int addOne(int[] a, int offset, int mlen, int carry) { offset = a.length - 1 - mlen - offset; long t = ((long)a[offset] & 4294967295L) + ((long)carry & 4294967295L); a[offset] = (int)t; if(t >>> 32 == 0L) { return 0; } else { do { --mlen; if(mlen < 0) { return 1; } --offset; if(offset < 0) { return 1; } ++a[offset]; } while(a[offset] == 0); return 0; } } private JDKBigInt modPow2(JDKBigInt exponent, int p) { JDKBigInt result = valueOf(1L); JDKBigInt baseToPow2 = this.mod2(p); int expOffset = 0; int limit = exponent.bitLength(); if(this.testBit(0)) { limit = p - 1 < limit?p - 1:limit; } while(expOffset < limit) { if(exponent.testBit(expOffset)) { result = result.multiply(baseToPow2).mod2(p); } ++expOffset; if(expOffset < limit) { baseToPow2 = baseToPow2.square().mod2(p); } } return result; } private JDKBigInt mod2(int p) { if(this.bitLength() <= p) { return this; } else { int numInts = p + 31 >>> 5; int[] mag = new int[numInts]; int excessBits; for(excessBits = 0; excessBits < numInts; ++excessBits) { mag[excessBits] = this.mag[excessBits + (this.mag.length - numInts)]; } excessBits = (numInts << 5) - p; mag[0] = (int)((long)mag[0] & (1L << 32 - excessBits) - 1L); return mag[0] == 0?new JDKBigInt(1, mag):new JDKBigInt(mag, 1); } } public JDKBigInt shiftLeft(int n) { if(this.signum == 0) { return ZERO; } else if(n == 0) { return this; } else if(n < 0) { if(n == -2147483648) { throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported."); } else { return this.shiftRight(-n); } } else { int nInts = n >>> 5; int nBits = n & 31; int magLen = this.mag.length; Object newMag = null; int i; int[] var10; if(nBits == 0) { var10 = new int[magLen + nInts]; for(i = 0; i < magLen; ++i) { var10[i] = this.mag[i]; } } else { i = 0; int nBits2 = 32 - nBits; int highBits = this.mag[0] >>> nBits2; if(highBits != 0) { var10 = new int[magLen + nInts + 1]; var10[i++] = highBits; } else { var10 = new int[magLen + nInts]; } int j; for(j = 0; j < magLen - 1; var10[i++] = this.mag[j++] << nBits | this.mag[j] >>> nBits2) { ; } var10[i] = this.mag[j] << nBits; } return new JDKBigInt(var10, this.signum); } } public JDKBigInt shiftRight(int n) { if(n == 0) { return this; } else if(n < 0) { if(n == -2147483648) { throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported."); } else { return this.shiftLeft(-n); } } else { int nInts = n >>> 5; int nBits = n & 31; int magLen = this.mag.length; Object newMag = null; if(nInts >= magLen) { return this.signum >= 0?ZERO:negConst[1]; } else { int onesLost; int i; int j; int[] var10; if(nBits == 0) { onesLost = magLen - nInts; var10 = new int[onesLost]; for(i = 0; i < onesLost; ++i) { var10[i] = this.mag[i]; } } else { onesLost = 0; i = this.mag[0] >>> nBits; if(i != 0) { var10 = new int[magLen - nInts]; var10[onesLost++] = i; } else { var10 = new int[magLen - nInts - 1]; } j = 32 - nBits; for(int j1 = 0; j1 < magLen - nInts - 1; var10[onesLost++] = this.mag[j1++] << j | this.mag[j1] >>> nBits) { ; } } if(this.signum < 0) { boolean var11 = false; i = magLen - 1; for(j = magLen - nInts; i >= j && !var11; --i) { var11 = this.mag[i] != 0; } if(!var11 && nBits != 0) { var11 = this.mag[magLen - nInts - 1] << 32 - nBits != 0; } if(var11) { var10 = this.javaIncrement(var10); } } return new JDKBigInt(var10, this.signum); } } } int[] javaIncrement(int[] val) { int lastSum = 0; for(int i = val.length - 1; i >= 0 && lastSum == 0; --i) { lastSum = ++val[i]; } if(lastSum == 0) { val = new int[val.length + 1]; val[0] = 1; } return val; } public JDKBigInt and(JDKBigInt val) { int[] result = new int[Math.max(this.intLength(), val.intLength())]; for(int i = 0; i < result.length; ++i) { result[i] = this.getInt(result.length - i - 1) & val.getInt(result.length - i - 1); } return valueOf(result); } public JDKBigInt or(JDKBigInt val) { int[] result = new int[Math.max(this.intLength(), val.intLength())]; for(int i = 0; i < result.length; ++i) { result[i] = this.getInt(result.length - i - 1) | val.getInt(result.length - i - 1); } return valueOf(result); } public JDKBigInt xor(JDKBigInt val) { int[] result = new int[Math.max(this.intLength(), val.intLength())]; for(int i = 0; i < result.length; ++i) { result[i] = this.getInt(result.length - i - 1) ^ val.getInt(result.length - i - 1); } return valueOf(result); } public JDKBigInt not() { int[] result = new int[this.intLength()]; for(int i = 0; i < result.length; ++i) { result[i] = ~this.getInt(result.length - i - 1); } return valueOf(result); } public JDKBigInt andNot(JDKBigInt val) { int[] result = new int[Math.max(this.intLength(), val.intLength())]; for(int i = 0; i < result.length; ++i) { result[i] = this.getInt(result.length - i - 1) & ~val.getInt(result.length - i - 1); } return valueOf(result); } public boolean testBit(int n) { if(n < 0) { throw new ArithmeticException("Negative bit address"); } else { return (this.getInt(n >>> 5) & 1 << (n & 31)) != 0; } } public JDKBigInt setBit(int n) { if(n < 0) { throw new ArithmeticException("Negative bit address"); } else { int intNum = n >>> 5; int[] result = new int[Math.max(this.intLength(), intNum + 2)]; for(int i = 0; i < result.length; ++i) { result[result.length - i - 1] = this.getInt(i); } result[result.length - intNum - 1] |= 1 << (n & 31); return valueOf(result); } } public JDKBigInt clearBit(int n) { if(n < 0) { throw new ArithmeticException("Negative bit address"); } else { int intNum = n >>> 5; int[] result = new int[Math.max(this.intLength(), (n + 1 >>> 5) + 1)]; for(int i = 0; i < result.length; ++i) { result[result.length - i - 1] = this.getInt(i); } result[result.length - intNum - 1] &= ~(1 << (n & 31)); return valueOf(result); } } public JDKBigInt flipBit(int n) { if(n < 0) { throw new ArithmeticException("Negative bit address"); } else { int intNum = n >>> 5; int[] result = new int[Math.max(this.intLength(), intNum + 2)]; for(int i = 0; i < result.length; ++i) { result[result.length - i - 1] = this.getInt(i); } result[result.length - intNum - 1] ^= 1 << (n & 31); return valueOf(result); } } public int getLowestSetBit() { int lsb = this.lowestSetBit - 2; if(lsb == -2) { byte var4 = 0; if(this.signum == 0) { lsb = var4 - 1; } else { int i; int b; for(i = 0; (b = this.getInt(i)) == 0; ++i) { ; } lsb = var4 + (i << 5) + Integer.numberOfTrailingZeros(b); } this.lowestSetBit = lsb + 2; } return lsb; } public int bitLength() { int n = this.bitLength - 1; if(n == -1) { int[] m = this.mag; int len = m.length; if(len == 0) { n = 0; } else { int magBitLength = (len - 1 << 5) + bitLengthForInt(this.mag[0]); if(this.signum < 0) { boolean pow2 = Integer.bitCount(this.mag[0]) == 1; for(int i = 1; i < len && pow2; ++i) { pow2 = this.mag[i] == 0; } n = pow2?magBitLength - 1:magBitLength; } else { n = magBitLength; } } this.bitLength = n + 1; } return n; } public int bitCount() { int bc = this.bitCount - 1; if(bc == -1) { bc = 0; int magTrailingZeroCount; for(magTrailingZeroCount = 0; magTrailingZeroCount < this.mag.length; ++magTrailingZeroCount) { bc += Integer.bitCount(this.mag[magTrailingZeroCount]); } if(this.signum < 0) { magTrailingZeroCount = 0; int j; for(j = this.mag.length - 1; this.mag[j] == 0; --j) { magTrailingZeroCount += 32; } magTrailingZeroCount += Integer.numberOfTrailingZeros(this.mag[j]); bc += magTrailingZeroCount - 1; } this.bitCount = bc + 1; } return bc; } public int compareTo(JDKBigInt val) { if(this.signum == val.signum) { switch(this.signum) { case -1: return val.compareMagnitude(this); case 1: return this.compareMagnitude(val); default: return 0; } } else { return this.signum > val.signum?1:-1; } } final int compareMagnitude(JDKBigInt val) { int[] m1 = this.mag; int len1 = m1.length; int[] m2 = val.mag; int len2 = m2.length; if(len1 < len2) { return -1; } else if(len1 > len2) { return 1; } else { for(int i = 0; i < len1; ++i) { int a = m1[i]; int b = m2[i]; if(a != b) { return ((long)a & 4294967295L) < ((long)b & 4294967295L)?-1:1; } } return 0; } } public boolean equals(Object x) { if(x == this) { return true; } else if(!(x instanceof JDKBigInt)) { return false; } else { JDKBigInt xInt = (JDKBigInt)x; if(xInt.signum != this.signum) { return false; } else { int[] m = this.mag; int len = m.length; int[] xm = xInt.mag; if(len != xm.length) { return false; } else { for(int i = 0; i < len; ++i) { if(xm[i] != m[i]) { return false; } } return true; } } } } public JDKBigInt min(JDKBigInt val) { return this.compareTo((JDKBigInt)val) < 0?this:val; } public JDKBigInt max(JDKBigInt val) { return this.compareTo((JDKBigInt)val) > 0?this:val; } public int hashCode() { int hashCode = 0; for(int i = 0; i < this.mag.length; ++i) { hashCode = (int)((long)(31 * hashCode) + ((long)this.mag[i] & 4294967295L)); } return hashCode * this.signum; } public byte[] toByteArray() { int byteLen = this.bitLength() / 8 + 1; byte[] byteArray = new byte[byteLen]; int i = byteLen - 1; int bytesCopied = 4; int nextInt = 0; for(int intIndex = 0; i >= 0; --i) { if(bytesCopied == 4) { nextInt = this.getInt(intIndex++); bytesCopied = 1; } else { nextInt >>>= 8; ++bytesCopied; } byteArray[i] = (byte)nextInt; } return byteArray; } public int intValue() { boolean result = false; int result1 = this.getInt(0); return result1; } public long longValue() { long result = 0L; for(int i = 1; i >= 0; --i) { result = (result << 32) + ((long)this.getInt(i) & 4294967295L); } return result; } public float floatValue() { return Float.parseFloat(this.toString()); } public double doubleValue() { return Double.parseDouble(this.toString()); } private static int[] stripLeadingZeroInts(int[] val) { int vlen = val.length; int keep; for(keep = 0; keep < vlen && val[keep] == 0; ++keep) { ; } return Arrays.copyOfRange(val, keep, vlen); } private static int[] trustedStripLeadingZeroInts(int[] val) { int vlen = val.length; int keep; for(keep = 0; keep < vlen && val[keep] == 0; ++keep) { ; } return keep == 0?val:Arrays.copyOfRange(val, keep, vlen); } private static int[] stripLeadingZeroBytes(byte[] a) { int byteLength = a.length; int keep; for(keep = 0; keep < byteLength && a[keep] == 0; ++keep) { ; } int intLength = byteLength - keep + 3 >>> 2; int[] result = new int[intLength]; int b = byteLength - 1; for(int i = intLength - 1; i >= 0; --i) { result[i] = a[b--] & 255; int bytesRemaining = b - keep + 1; int bytesToTransfer = Math.min(3, bytesRemaining); for(int j = 8; j <= bytesToTransfer << 3; j += 8) { result[i] |= (a[b--] & 255) << j; } } return result; } private static int[] makePositive(byte[] a) { int byteLength = a.length; int keep; for(keep = 0; keep < byteLength && a[keep] == -1; ++keep) { ; } int k; for(k = keep; k < byteLength && a[k] == 0; ++k) { ; } int extraByte = k == byteLength?1:0; int intLength = (byteLength - keep + extraByte + 3) / 4; int[] result = new int[intLength]; int b = byteLength - 1; int i; for(i = intLength - 1; i >= 0; --i) { result[i] = a[b--] & 255; int numBytesToTransfer = Math.min(3, b - keep + 1); if(numBytesToTransfer < 0) { numBytesToTransfer = 0; } int mask; for(mask = 8; mask <= 8 * numBytesToTransfer; mask += 8) { result[i] |= (a[b--] & 255) << mask; } mask = -1 >>> 8 * (3 - numBytesToTransfer); result[i] = ~result[i] & mask; } for(i = result.length - 1; i >= 0; --i) { result[i] = (int)(((long)result[i] & 4294967295L) + 1L); if(result[i] != 0) { break; } } return result; } private static int[] makePositive(int[] a) { int keep; for(keep = 0; keep < a.length && a[keep] == -1; ++keep) { ; } int j; for(j = keep; j < a.length && a[j] == 0; ++j) { ; } int extraInt = j == a.length?1:0; int[] result = new int[a.length - keep + extraInt]; int i; for(i = keep; i < a.length; ++i) { result[i - keep + extraInt] = ~a[i]; } for(i = result.length - 1; ++result[i] == 0; --i) { ; } return result; } private int intLength() { return (this.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 n) { if(n < 0) { return 0; } else if(n >= this.mag.length) { return this.signInt(); } else { int magInt = this.mag[this.mag.length - n - 1]; return this.signum >= 0?magInt:(n <= this.firstNonzeroIntNum()?-magInt:~magInt); } } private int firstNonzeroIntNum() { int fn = this.firstNonzeroIntNum - 2; if(fn == -2) { boolean var4 = false; int mlen = this.mag.length; int i; for(i = mlen - 1; i >= 0 && this.mag[i] == 0; --i) { ; } fn = mlen - i - 1; this.firstNonzeroIntNum = fn + 2; } return fn; } private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { ObjectInputStream.GetField fields = s.readFields(); int sign = fields.get("signum", -2); byte[] magnitude = (byte[])((byte[])fields.get("magnitude", (Object)null)); String message; if(sign >= -1 && sign <= 1) { if(magnitude.length == 0 != (sign == 0)) { message = "JDKBigInt: signum-magnitude mismatch"; if(fields.defaulted("magnitude")) { message = "JDKBigInt: Magnitude not present in stream"; } throw new StreamCorruptedException(message); } else { unsafe.putIntVolatile(this, signumOffset, sign); unsafe.putObjectVolatile(this, magOffset, stripLeadingZeroBytes(magnitude)); } } else { message = "JDKBigInt: Invalid signum value"; if(fields.defaulted("signum")) { message = "JDKBigInt: Signum not present in stream"; } throw new StreamCorruptedException(message); } } private void writeObject(ObjectOutputStream s) throws IOException { ObjectOutputStream.PutField fields = s.putFields(); fields.put("signum", this.signum); fields.put("magnitude", this.magSerializedForm()); fields.put("bitCount", -1); fields.put("bitLength", -1); fields.put("lowestSetBit", -2); fields.put("firstNonzeroByteNum", -2); s.writeFields(); } private byte[] magSerializedForm() { int len = this.mag.length; int bitLen = len == 0?0:(len - 1 << 5) + bitLengthForInt(this.mag[0]); int byteLen = bitLen + 7 >>> 3; byte[] result = new byte[byteLen]; int i = byteLen - 1; int bytesCopied = 4; int intIndex = len - 1; for(int nextInt = 0; i >= 0; --i) { if(bytesCopied == 4) { nextInt = this.mag[intIndex--]; bytesCopied = 1; } else { nextInt >>>= 8; ++bytesCopied; } result[i] = (byte)nextInt; } return result; } static { int ex; for(ex = 1; ex <= 16; ++ex) { int[] magnitude = new int[]{ex}; posConst[ex] = new JDKBigInt(magnitude, 1); negConst[ex] = new JDKBigInt(magnitude, -1); } ZERO = new JDKBigInt(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(ex = 0; ex < 63; ++ex) { zeros[ex] = zeros[63].substring(0, ex); } 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 JDKBigInt[]{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", byte[].class), new ObjectStreamField("bitCount", Integer.TYPE), new ObjectStreamField("bitLength", Integer.TYPE), new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE), new ObjectStreamField("lowestSetBit", Integer.TYPE)}; unsafe = null;//Unsafe.getUnsafe(); signumOffset = 0; magOffset = 0; // try { // signumOffset = unsafe.objectFieldOffset(JDKBigInt.class.getDeclaredField("signum")); // magOffset = unsafe.objectFieldOffset(JDKBigInt.class.getDeclaredField("mag")); // } catch (Exception var2) { // throw new Error(var2); // } } }