home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 1999 April / DPPCPRO0499.ISO / April / Notes / 50b2wic.exe / DATA1.CAB / NotesProgramFilesJavaSupport / rt.jar / java / math / BigInteger.class (.txt) < prev   
Encoding:
Java Class File  |  1998-04-23  |  24.6 KB  |  916 lines

  1. package java.math;
  2.  
  3. import java.util.Random;
  4.  
  5. public class BigInteger extends Number {
  6.    private int signum;
  7.    private byte[] magnitude;
  8.    private int bitCount;
  9.    private int bitLength;
  10.    private int firstNonzeroByteNum;
  11.    private int lowestSetBit;
  12.    private static final BigInteger ZERO = new BigInteger(new byte[0], 0);
  13.    private static final int MAX_CONSTANT = 16;
  14.    private static BigInteger[] posConst = new BigInteger[17];
  15.    private static BigInteger[] negConst = new BigInteger[17];
  16.    private static final byte[] bitLen;
  17.    private static final byte[] bitCnt;
  18.    private static final byte[] trailingZeroCnt;
  19.    private static String[] zeros;
  20.    private static final BigInteger ONE;
  21.    private static final BigInteger TWO;
  22.    private static final char ZERO_CHAR;
  23.    private static int[] digitsPerLong;
  24.    private static BigInteger[] longRadix;
  25.  
  26.    public BigInteger(byte[] var1) throws NumberFormatException {
  27.       this.bitCount = -1;
  28.       this.bitLength = -1;
  29.       this.firstNonzeroByteNum = -2;
  30.       this.lowestSetBit = -2;
  31.       if (var1.length == 0) {
  32.          throw new NumberFormatException("Zero length BigInteger");
  33.       } else if (var1[0] < 0) {
  34.          this.magnitude = makePositive(var1);
  35.          this.signum = -1;
  36.       } else {
  37.          this.magnitude = stripLeadingZeroBytes(var1);
  38.          this.signum = this.magnitude.length == 0 ? 0 : 1;
  39.       }
  40.    }
  41.  
  42.    public BigInteger(int var1, byte[] var2) throws NumberFormatException {
  43.       this.bitCount = -1;
  44.       this.bitLength = -1;
  45.       this.firstNonzeroByteNum = -2;
  46.       this.lowestSetBit = -2;
  47.       this.magnitude = stripLeadingZeroBytes(var2);
  48.       if (var1 >= -1 && var1 <= 1) {
  49.          if (this.magnitude.length == 0) {
  50.             this.signum = 0;
  51.          } else if (var1 == 0) {
  52.             throw new NumberFormatException("signum-magnitude mismatch");
  53.          } else {
  54.             this.signum = var1;
  55.          }
  56.       } else {
  57.          throw new NumberFormatException("Invalid signum value");
  58.       }
  59.    }
  60.  
  61.    public BigInteger(String var1, int var2) throws NumberFormatException {
  62.       this.bitCount = -1;
  63.       this.bitLength = -1;
  64.       this.firstNonzeroByteNum = -2;
  65.       this.lowestSetBit = -2;
  66.       int var3 = 0;
  67.       if (var2 >= 2 && var2 <= 36) {
  68.          if (var1.length() == 0) {
  69.             throw new NumberFormatException("Zero length BigInteger");
  70.          } else {
  71.             this.signum = 1;
  72.             if (var1.charAt(0) == '-') {
  73.                if (var1.length() == 1) {
  74.                   throw new NumberFormatException("Zero length BigInteger");
  75.                }
  76.  
  77.                this.signum = -1;
  78.                var3 = 1;
  79.             }
  80.  
  81.             while(var3 < var1.length() && var1.charAt(var3) == ZERO_CHAR) {
  82.                ++var3;
  83.             }
  84.  
  85.             if (var3 == var1.length()) {
  86.                this.signum = 0;
  87.                this.magnitude = new byte[0];
  88.             } else {
  89.                int var4 = var1.length() - var3;
  90.                int var5 = var4 % digitsPerLong[var2];
  91.                if (var5 == 0) {
  92.                   var5 = digitsPerLong[var2];
  93.                }
  94.  
  95.                int var10;
  96.                String var6 = var1.substring(var3, var10 = var3 + var5);
  97.  
  98.                BigInteger var7;
  99.                long var8;
  100.                for(var7 = valueOf(Long.parseLong(var6, var2)); var10 < var1.length(); var7 = var7.multiply(longRadix[var2]).add(valueOf(var8))) {
  101.                   var6 = var1.substring(var10, var10 += digitsPerLong[var2]);
  102.                   var8 = Long.parseLong(var6, var2);
  103.                   if (var8 < 0L) {
  104.                      throw new NumberFormatException("Illegal digit");
  105.                   }
  106.                }
  107.  
  108.                this.magnitude = var7.magnitude;
  109.             }
  110.          }
  111.       } else {
  112.          throw new NumberFormatException("Radix out of range");
  113.       }
  114.    }
  115.  
  116.    public BigInteger(String var1) throws NumberFormatException {
  117.       this((String)var1, 10);
  118.    }
  119.  
  120.    public BigInteger(int var1, Random var2) throws IllegalArgumentException {
  121.       this(1, (byte[])randomBits(var1, var2));
  122.    }
  123.  
  124.    private static byte[] randomBits(int var0, Random var1) throws IllegalArgumentException {
  125.       if (var0 < 0) {
  126.          throw new IllegalArgumentException("numBits must be non-negative");
  127.       } else {
  128.          int var2 = (var0 + 7) / 8;
  129.          byte[] var3 = new byte[var2];
  130.          if (var2 > 0) {
  131.             var1.nextBytes(var3);
  132.             int var4 = 8 * var2 - var0;
  133.             var3[0] = (byte)(var3[0] & (1 << 8 - var4) - 1);
  134.          }
  135.  
  136.          return var3;
  137.       }
  138.    }
  139.  
  140.    public BigInteger(int var1, int var2, Random var3) {
  141.       this.bitCount = -1;
  142.       this.bitLength = -1;
  143.       this.firstNonzeroByteNum = -2;
  144.       this.lowestSetBit = -2;
  145.       if (var1 < 2) {
  146.          throw new ArithmeticException("bitLength < 2");
  147.       } else {
  148.          BigInteger var5;
  149.          do {
  150.             var5 = (new BigInteger(var1 - 1, var3)).setBit(var1 - 1);
  151.             var5 = var1 <= 16 ? (var1 > 2 ? var5.setBit(0) : var5) : new BigInteger(plumbGeneratePrime(var5.magnitude), 1);
  152.          } while(var5.bitLength() != var1 || !var5.isProbablePrime(var2));
  153.  
  154.          this.signum = 1;
  155.          this.magnitude = var5.magnitude;
  156.       }
  157.    }
  158.  
  159.    private BigInteger(byte[] var1, int var2) {
  160.       this.bitCount = -1;
  161.       this.bitLength = -1;
  162.       this.firstNonzeroByteNum = -2;
  163.       this.lowestSetBit = -2;
  164.       this.signum = var1.length == 0 ? 0 : var2;
  165.       this.magnitude = var1;
  166.    }
  167.  
  168.    public static BigInteger valueOf(long var0) {
  169.       if (var0 == 0L) {
  170.          return ZERO;
  171.       } else if (var0 > 0L && var0 <= 16L) {
  172.          return posConst[(int)var0];
  173.       } else if (var0 < 0L && var0 >= -16L) {
  174.          return negConst[(int)(-var0)];
  175.       } else {
  176.          byte[] var2 = new byte[8];
  177.  
  178.          for(int var3 = 0; var3 < 8; var0 >>= 8) {
  179.             var2[7 - var3] = (byte)((int)var0);
  180.             ++var3;
  181.          }
  182.  
  183.          return new BigInteger(var2);
  184.       }
  185.    }
  186.  
  187.    private static BigInteger valueOf(byte[] var0) {
  188.       return var0[0] > 0 ? new BigInteger(var0, 1) : new BigInteger(var0);
  189.    }
  190.  
  191.    public BigInteger add(BigInteger var1) throws ArithmeticException {
  192.       if (var1.signum == 0) {
  193.          return this;
  194.       } else if (this.signum == 0) {
  195.          return var1;
  196.       } else if (var1.signum == this.signum) {
  197.          return new BigInteger(plumbAdd(this.magnitude, var1.magnitude), this.signum);
  198.       } else {
  199.          return this.signum < 0 ? plumbSubtract(var1.magnitude, this.magnitude) : plumbSubtract(this.magnitude, var1.magnitude);
  200.       }
  201.    }
  202.  
  203.    public BigInteger subtract(BigInteger var1) {
  204.       return this.add(new BigInteger(var1.magnitude, -var1.signum));
  205.    }
  206.  
  207.    public BigInteger multiply(BigInteger var1) {
  208.       return var1.signum != 0 && this.signum != 0 ? new BigInteger(plumbMultiply(this.magnitude, var1.magnitude), this.signum * var1.signum) : ZERO;
  209.    }
  210.  
  211.    public BigInteger divide(BigInteger var1) throws ArithmeticException {
  212.       if (var1.signum == 0) {
  213.          throw new ArithmeticException("BigInteger divide by zero");
  214.       } else {
  215.          return this.signum == 0 ? ZERO : new BigInteger(plumbDivide(this.magnitude, var1.magnitude), this.signum * var1.signum);
  216.       }
  217.    }
  218.  
  219.    public BigInteger remainder(BigInteger var1) throws ArithmeticException {
  220.       if (var1.signum == 0) {
  221.          throw new ArithmeticException("BigInteger divide by zero");
  222.       } else if (this.signum == 0) {
  223.          return ZERO;
  224.       } else {
  225.          return this.magnitude.length < var1.magnitude.length ? this : new BigInteger(plumbRemainder(this.magnitude, var1.magnitude), this.signum);
  226.       }
  227.    }
  228.  
  229.    public BigInteger[] divideAndRemainder(BigInteger var1) throws ArithmeticException {
  230.       BigInteger[] var2 = new BigInteger[2];
  231.       if (var1.signum == 0) {
  232.          throw new ArithmeticException("BigInteger divide by zero");
  233.       } else {
  234.          if (this.signum == 0) {
  235.             var2[0] = var2[1] = ZERO;
  236.          } else if (this.magnitude.length < var1.magnitude.length) {
  237.             var2[0] = ZERO;
  238.             var2[1] = this;
  239.          } else {
  240.             byte[][] var3 = plumbDivideAndRemainder(this.magnitude, var1.magnitude);
  241.             var2[0] = new BigInteger(var3[0], this.signum * var1.signum);
  242.             var2[1] = new BigInteger(var3[1], this.signum);
  243.          }
  244.  
  245.          return var2;
  246.       }
  247.    }
  248.  
  249.    public BigInteger pow(int var1) throws ArithmeticException {
  250.       if (var1 < 0) {
  251.          throw new ArithmeticException("Negative exponent");
  252.       } else if (this.signum == 0) {
  253.          return var1 == 0 ? ONE : this;
  254.       } else {
  255.          BigInteger var2 = valueOf((long)(var1 < 0 && (var1 & 1) == 1 ? -1 : 1));
  256.          BigInteger var3 = this;
  257.  
  258.          while(var1 != 0) {
  259.             if ((var1 & 1) == 1) {
  260.                var2 = var2.multiply(var3);
  261.             }
  262.  
  263.             if ((var1 >>= 1) != 0) {
  264.                var3 = new BigInteger(plumbSquare(var3.magnitude), 1);
  265.             }
  266.          }
  267.  
  268.          return var2;
  269.       }
  270.    }
  271.  
  272.    public BigInteger gcd(BigInteger var1) {
  273.       if (var1.signum == 0) {
  274.          return this.abs();
  275.       } else {
  276.          return this.signum == 0 ? var1.abs() : new BigInteger(plumbGcd(this.magnitude, var1.magnitude), 1);
  277.       }
  278.    }
  279.  
  280.    public BigInteger abs() {
  281.       return this.signum >= 0 ? this : this.negate();
  282.    }
  283.  
  284.    public BigInteger negate() {
  285.       return new BigInteger(this.magnitude, -this.signum);
  286.    }
  287.  
  288.    public int signum() {
  289.       return this.signum;
  290.    }
  291.  
  292.    public BigInteger mod(BigInteger var1) {
  293.       if (var1.signum <= 0) {
  294.          throw new ArithmeticException("BigInteger: modulus not positive");
  295.       } else {
  296.          BigInteger var2 = this.remainder(var1);
  297.          return var2.signum >= 0 ? var2 : var2.add(var1);
  298.       }
  299.    }
  300.  
  301.    public BigInteger modPow(BigInteger var1, BigInteger var2) {
  302.       if (var2.signum <= 0) {
  303.          throw new ArithmeticException("BigInteger: modulus not positive");
  304.       } else if (var1.signum == 0) {
  305.          return ONE;
  306.       } else {
  307.          boolean var3;
  308.          if (var3 = var1.signum < 0) {
  309.             var1 = var1.negate();
  310.          }
  311.  
  312.          BigInteger var4 = this.signum >= 0 && this.compareTo(var2) < 0 ? this : this.mod(var2);
  313.          BigInteger var5;
  314.          if (var2.testBit(0)) {
  315.             var5 = new BigInteger(plumbModPow(var4.magnitude, var1.magnitude, var2.magnitude), 1);
  316.          } else {
  317.             int var6 = var2.getLowestSetBit();
  318.             BigInteger var7 = var2.shiftRight(var6);
  319.             BigInteger var8 = ONE.shiftLeft(var6);
  320.             BigInteger var9 = new BigInteger(plumbModPow(var4.magnitude, var1.magnitude, var7.magnitude), 1);
  321.             BigInteger var10 = var4.modPow2(var1, var6);
  322.             BigInteger var11 = var8.modInverse(var7);
  323.             BigInteger var12 = var7.modInverse(var8);
  324.             var5 = var9.multiply(var8).multiply(var11).add(var10.multiply(var7).multiply(var12)).mod(var2);
  325.          }
  326.  
  327.          return var3 ? var5.modInverse(var2) : var5;
  328.       }
  329.    }
  330.  
  331.    private BigInteger modPow2(BigInteger var1, int var2) {
  332.       BigInteger var3 = valueOf(1L);
  333.       BigInteger var4 = this.mod2(var2);
  334.  
  335.       while(var1.signum != 0) {
  336.          if (var1.testBit(0)) {
  337.             var3 = var3.multiply(var4).mod2(var2);
  338.          }
  339.  
  340.          var1 = var1.shiftRight(1);
  341.          if (var1.signum != 0) {
  342.             var4 = (new BigInteger(plumbSquare(var4.magnitude), 1)).mod2(var2);
  343.          }
  344.       }
  345.  
  346.       return var3;
  347.    }
  348.  
  349.    private BigInteger mod2(int var1) {
  350.       if (this.bitLength() <= var1) {
  351.          return this;
  352.       } else {
  353.          int var2 = (var1 + 7) / 8;
  354.          byte[] var3 = new byte[var2];
  355.  
  356.          for(int var4 = 0; var4 < var2; ++var4) {
  357.             var3[var4] = this.magnitude[var4 + (this.magnitude.length - var2)];
  358.          }
  359.  
  360.          int var5 = 8 * var2 - var1;
  361.          var3[0] = (byte)(var3[0] & (1 << 8 - var5) - 1);
  362.          return var3[0] == 0 ? new BigInteger(1, var3) : new BigInteger(var3, 1);
  363.       }
  364.    }
  365.  
  366.    public BigInteger modInverse(BigInteger var1) throws ArithmeticException {
  367.       if (var1.signum != 1) {
  368.          throw new ArithmeticException("BigInteger: modulus not positive");
  369.       } else {
  370.          BigInteger var2 = this.remainder(var1);
  371.          if (var2.signum < 0) {
  372.             var2 = var2.add(var1);
  373.          }
  374.  
  375.          if (!var2.gcd(var1).equals(ONE)) {
  376.             throw new ArithmeticException("BigInteger not invertible");
  377.          } else {
  378.             return new BigInteger(plumbModInverse(var2.magnitude, var1.magnitude), 1);
  379.          }
  380.       }
  381.    }
  382.  
  383.    public BigInteger shiftLeft(int var1) {
  384.       if (var1 == 0) {
  385.          return this;
  386.       } else if (var1 < 0) {
  387.          return this.shiftRight(-var1);
  388.       } else {
  389.          int var2 = var1 / 8;
  390.          int var3 = var1 % 8;
  391.          byte[] var4 = new byte[(this.bitLength() + var1) / 8 + 1];
  392.          if (var3 == 0) {
  393.             for(int var5 = var2; var5 < var4.length; ++var5) {
  394.                var4[var4.length - 1 - var5] = this.getByte(var5 - var2);
  395.             }
  396.          } else {
  397.             for(int var6 = var2; var6 < var4.length; ++var6) {
  398.                var4[var4.length - 1 - var6] = (byte)(this.getByte(var6 - var2) << var3 | (var6 == var2 ? 0 : (this.getByte(var6 - var2 - 1) & 255) >> 8 - var3));
  399.             }
  400.          }
  401.  
  402.          return valueOf(var4);
  403.       }
  404.    }
  405.  
  406.    public BigInteger shiftRight(int var1) {
  407.       if (var1 == 0) {
  408.          return this;
  409.       } else if (var1 < 0) {
  410.          return this.shiftLeft(-var1);
  411.       } else if (var1 >= this.bitLength()) {
  412.          return this.signum < 0 ? valueOf(-1L) : ZERO;
  413.       } else {
  414.          int var2 = var1 / 8;
  415.          int var3 = var1 % 8;
  416.          byte[] var4 = new byte[(this.bitLength - var1) / 8 + 1];
  417.          if (var3 == 0) {
  418.             for(int var5 = 0; var5 < var4.length; ++var5) {
  419.                var4[var4.length - 1 - var5] = this.getByte(var2 + var5);
  420.             }
  421.          } else {
  422.             for(int var6 = 0; var6 < var4.length; ++var6) {
  423.                var4[var4.length - 1 - var6] = (byte)((this.getByte(var2 + var6 + 1) << 8 | this.getByte(var2 + var6) & 255) >> var3);
  424.             }
  425.          }
  426.  
  427.          return valueOf(var4);
  428.       }
  429.    }
  430.  
  431.    public BigInteger and(BigInteger var1) {
  432.       byte[] var2 = new byte[Math.max(this.byteLength(), var1.byteLength())];
  433.  
  434.       for(int var3 = 0; var3 < var2.length; ++var3) {
  435.          var2[var3] = (byte)(this.getByte(var2.length - var3 - 1) & var1.getByte(var2.length - var3 - 1));
  436.       }
  437.  
  438.       return valueOf(var2);
  439.    }
  440.  
  441.    // $FF: renamed from: or (java.math.BigInteger) java.math.BigInteger
  442.    public BigInteger method_0(BigInteger var1) {
  443.       byte[] var2 = new byte[Math.max(this.byteLength(), var1.byteLength())];
  444.  
  445.       for(int var3 = 0; var3 < var2.length; ++var3) {
  446.          var2[var3] = (byte)(this.getByte(var2.length - var3 - 1) | var1.getByte(var2.length - var3 - 1));
  447.       }
  448.  
  449.       return valueOf(var2);
  450.    }
  451.  
  452.    public BigInteger xor(BigInteger var1) {
  453.       byte[] var2 = new byte[Math.max(this.byteLength(), var1.byteLength())];
  454.  
  455.       for(int var3 = 0; var3 < var2.length; ++var3) {
  456.          var2[var3] = (byte)(this.getByte(var2.length - var3 - 1) ^ var1.getByte(var2.length - var3 - 1));
  457.       }
  458.  
  459.       return valueOf(var2);
  460.    }
  461.  
  462.    public BigInteger not() {
  463.       byte[] var1 = new byte[this.byteLength()];
  464.  
  465.       for(int var2 = 0; var2 < var1.length; ++var2) {
  466.          var1[var2] = (byte)(~this.getByte(var1.length - var2 - 1));
  467.       }
  468.  
  469.       return valueOf(var1);
  470.    }
  471.  
  472.    public BigInteger andNot(BigInteger var1) {
  473.       byte[] var2 = new byte[Math.max(this.byteLength(), var1.byteLength())];
  474.  
  475.       for(int var3 = 0; var3 < var2.length; ++var3) {
  476.          var2[var3] = (byte)(this.getByte(var2.length - var3 - 1) & ~var1.getByte(var2.length - var3 - 1));
  477.       }
  478.  
  479.       return valueOf(var2);
  480.    }
  481.  
  482.    public boolean testBit(int var1) throws ArithmeticException {
  483.       if (var1 < 0) {
  484.          throw new ArithmeticException("Negative bit address");
  485.       } else {
  486.          return (this.getByte(var1 / 8) & 1 << var1 % 8) != 0;
  487.       }
  488.    }
  489.  
  490.    public BigInteger setBit(int var1) throws ArithmeticException {
  491.       if (var1 < 0) {
  492.          throw new ArithmeticException("Negative bit address");
  493.       } else {
  494.          int var2 = var1 / 8;
  495.          byte[] var3 = new byte[Math.max(this.byteLength(), var2 + 2)];
  496.  
  497.          for(int var4 = 0; var4 < var3.length; ++var4) {
  498.             var3[var3.length - var4 - 1] = this.getByte(var4);
  499.          }
  500.  
  501.          var3[var3.length - var2 - 1] = (byte)(var3[var3.length - var2 - 1] | 1 << var1 % 8);
  502.          return valueOf(var3);
  503.       }
  504.    }
  505.  
  506.    public BigInteger clearBit(int var1) throws ArithmeticException {
  507.       if (var1 < 0) {
  508.          throw new ArithmeticException("Negative bit address");
  509.       } else {
  510.          int var2 = var1 / 8;
  511.          byte[] var3 = new byte[Math.max(this.byteLength(), (var1 + 1) / 8 + 1)];
  512.  
  513.          for(int var4 = 0; var4 < var3.length; ++var4) {
  514.             var3[var3.length - var4 - 1] = this.getByte(var4);
  515.          }
  516.  
  517.          var3[var3.length - var2 - 1] = (byte)(var3[var3.length - var2 - 1] & ~(1 << var1 % 8));
  518.          return valueOf(var3);
  519.       }
  520.    }
  521.  
  522.    public BigInteger flipBit(int var1) throws ArithmeticException {
  523.       if (var1 < 0) {
  524.          throw new ArithmeticException("Negative bit address");
  525.       } else {
  526.          int var2 = var1 / 8;
  527.          byte[] var3 = new byte[Math.max(this.byteLength(), var2 + 2)];
  528.  
  529.          for(int var4 = 0; var4 < var3.length; ++var4) {
  530.             var3[var3.length - var4 - 1] = this.getByte(var4);
  531.          }
  532.  
  533.          var3[var3.length - var2 - 1] = (byte)(var3[var3.length - var2 - 1] ^ 1 << var1 % 8);
  534.          return valueOf(var3);
  535.       }
  536.    }
  537.  
  538.    public int getLowestSetBit() {
  539.       if (this.lowestSetBit == -2) {
  540.          if (this.signum == 0) {
  541.             this.lowestSetBit = -1;
  542.          } else {
  543.             int var1;
  544.             byte var2;
  545.             for(var1 = 0; (var2 = this.getByte(var1)) == 0; ++var1) {
  546.             }
  547.  
  548.             this.lowestSetBit = 8 * var1 + trailingZeroCnt[var2 & 255];
  549.          }
  550.       }
  551.  
  552.       return this.lowestSetBit;
  553.    }
  554.  
  555.    public int bitLength() {
  556.       if (this.bitLength == -1) {
  557.          if (this.signum == 0) {
  558.             this.bitLength = 0;
  559.          } else {
  560.             int var1 = 8 * (this.magnitude.length - 1) + bitLen[this.magnitude[0] & 255];
  561.             if (this.signum < 0) {
  562.                boolean var2 = bitCnt[this.magnitude[0] & 255] == 1;
  563.  
  564.                for(int var3 = 1; var3 < this.magnitude.length && var2; ++var3) {
  565.                   var2 = this.magnitude[var3] == 0;
  566.                }
  567.  
  568.                this.bitLength = var2 ? var1 - 1 : var1;
  569.             } else {
  570.                this.bitLength = var1;
  571.             }
  572.          }
  573.       }
  574.  
  575.       return this.bitLength;
  576.    }
  577.  
  578.    public int bitCount() {
  579.       if (this.bitCount == -1) {
  580.          int var1 = 0;
  581.  
  582.          for(int var2 = 0; var2 < this.magnitude.length; ++var2) {
  583.             var1 += bitCnt[this.magnitude[var2] & 255];
  584.          }
  585.  
  586.          if (this.signum < 0) {
  587.             int var3 = 0;
  588.  
  589.             int var4;
  590.             for(var4 = this.magnitude.length - 1; this.magnitude[var4] == 0; --var4) {
  591.                var3 += 8;
  592.             }
  593.  
  594.             var3 += trailingZeroCnt[this.magnitude[var4] & 255];
  595.             this.bitCount = var1 + var3 - 1;
  596.          } else {
  597.             this.bitCount = var1;
  598.          }
  599.       }
  600.  
  601.       return this.bitCount;
  602.    }
  603.  
  604.    public boolean isProbablePrime(int var1) {
  605.       int var2 = var1 / 2;
  606.       if (var2 <= 0) {
  607.          return true;
  608.       } else {
  609.          BigInteger var3 = this.abs();
  610.          if (var3.equals(TWO)) {
  611.             return true;
  612.          } else if (var3.testBit(0) && !var3.equals(ONE)) {
  613.             BigInteger var4 = var3.subtract(ONE);
  614.             int var5 = var4.getLowestSetBit();
  615.             var4 = var4.shiftRight(var5);
  616.             Random var6 = new Random();
  617.  
  618.             for(int var7 = 0; var7 < var2; ++var7) {
  619.                BigInteger var8;
  620.                do {
  621.                   var8 = new BigInteger(var3.bitLength(), var6);
  622.                } while(var8.compareTo(ONE) <= 0 || var8.compareTo(var3) >= 0);
  623.  
  624.                int var9 = 0;
  625.  
  626.                for(BigInteger var10 = var8.modPow(var4, var3); (var9 != 0 || !var10.equals(ONE)) && !var10.equals(var3.subtract(ONE)); var10 = var10.modPow(TWO, var3)) {
  627.                   if (var9 > 0 && var10.equals(ONE)) {
  628.                      return false;
  629.                   }
  630.  
  631.                   ++var9;
  632.                   if (var9 == var5) {
  633.                      return false;
  634.                   }
  635.                }
  636.             }
  637.  
  638.             return true;
  639.          } else {
  640.             return false;
  641.          }
  642.       }
  643.    }
  644.  
  645.    public int compareTo(BigInteger var1) {
  646.       if (this.signum == var1.signum) {
  647.          return this.signum * byteArrayCmp(this.magnitude, var1.magnitude);
  648.       } else {
  649.          return this.signum > var1.signum ? 1 : -1;
  650.       }
  651.    }
  652.  
  653.    private static int byteArrayCmp(byte[] var0, byte[] var1) {
  654.       if (var0.length < var1.length) {
  655.          return -1;
  656.       } else if (var0.length > var1.length) {
  657.          return 1;
  658.       } else {
  659.          for(int var2 = 0; var2 < var0.length; ++var2) {
  660.             int var3 = var0[var2] & 255;
  661.             int var4 = var1[var2] & 255;
  662.             if (var3 < var4) {
  663.                return -1;
  664.             }
  665.  
  666.             if (var3 > var4) {
  667.                return 1;
  668.             }
  669.          }
  670.  
  671.          return 0;
  672.       }
  673.    }
  674.  
  675.    public boolean equals(Object var1) {
  676.       if (!(var1 instanceof BigInteger)) {
  677.          return false;
  678.       } else {
  679.          BigInteger var2 = (BigInteger)var1;
  680.          if (var2.signum == this.signum && var2.magnitude.length == this.magnitude.length) {
  681.             if (var2 == this) {
  682.                return true;
  683.             } else {
  684.                for(int var3 = 0; var3 < this.magnitude.length; ++var3) {
  685.                   if (var2.magnitude[var3] != this.magnitude[var3]) {
  686.                      return false;
  687.                   }
  688.                }
  689.  
  690.                return true;
  691.             }
  692.          } else {
  693.             return false;
  694.          }
  695.       }
  696.    }
  697.  
  698.    public BigInteger min(BigInteger var1) {
  699.       return this.compareTo(var1) < 0 ? this : var1;
  700.    }
  701.  
  702.    public BigInteger max(BigInteger var1) {
  703.       return this.compareTo(var1) > 0 ? this : var1;
  704.    }
  705.  
  706.    public int hashCode() {
  707.       int var1 = 0;
  708.  
  709.       for(int var2 = 0; var2 < this.magnitude.length; ++var2) {
  710.          var1 = 37 * var1 + (this.magnitude[var2] & 255);
  711.       }
  712.  
  713.       return var1 * this.signum;
  714.    }
  715.  
  716.    public String toString(int var1) {
  717.       if (this.signum == 0) {
  718.          return "0";
  719.       } else {
  720.          if (var1 < 2 || var1 > 36) {
  721.             var1 = 10;
  722.          }
  723.  
  724.          int var2 = (this.magnitude.length + 6) / 7;
  725.          String[] var3 = new String[var2];
  726.          BigInteger var4 = this.abs();
  727.  
  728.          int var5;
  729.          BigInteger[] var6;
  730.          for(var5 = 0; var4.signum != 0; var4 = var6[0]) {
  731.             var6 = var4.divideAndRemainder(longRadix[var1]);
  732.             var3[var5++] = Long.toString(var6[1].longValue(), var1);
  733.          }
  734.  
  735.          StringBuffer var9 = new StringBuffer(var5 * digitsPerLong[var1] + 1);
  736.          if (this.signum < 0) {
  737.             var9.append('-');
  738.          }
  739.  
  740.          var9.append(var3[var5 - 1]);
  741.  
  742.          for(int var7 = var5 - 2; var7 >= 0; --var7) {
  743.             int var8 = digitsPerLong[var1] - var3[var7].length();
  744.             if (var8 != 0) {
  745.                var9.append(zeros[var8]);
  746.             }
  747.  
  748.             var9.append(var3[var7]);
  749.          }
  750.  
  751.          return var9.toString();
  752.       }
  753.    }
  754.  
  755.    public String toString() {
  756.       return this.toString(10);
  757.    }
  758.  
  759.    public byte[] toByteArray() {
  760.       byte[] var1 = new byte[this.byteLength()];
  761.  
  762.       for(int var2 = 0; var2 < var1.length; ++var2) {
  763.          var1[var2] = this.getByte(var1.length - var2 - 1);
  764.       }
  765.  
  766.       return var1;
  767.    }
  768.  
  769.    public int intValue() {
  770.       int var1 = 0;
  771.  
  772.       for(int var2 = 3; var2 >= 0; --var2) {
  773.          var1 = (var1 << 8) + (this.getByte(var2) & 255);
  774.       }
  775.  
  776.       return var1;
  777.    }
  778.  
  779.    public long longValue() {
  780.       long var1 = 0L;
  781.  
  782.       for(int var3 = 7; var3 >= 0; --var3) {
  783.          var1 = (var1 << 8) + (long)(this.getByte(var3) & 255);
  784.       }
  785.  
  786.       return var1;
  787.    }
  788.  
  789.    public float floatValue() {
  790.       return Float.valueOf(this.toString());
  791.    }
  792.  
  793.    public double doubleValue() {
  794.       return Double.valueOf(this.toString());
  795.    }
  796.  
  797.    private static byte[] stripLeadingZeroBytes(byte[] var0) {
  798.       int var1;
  799.       for(var1 = 0; var1 < var0.length && var0[var1] == 0; ++var1) {
  800.       }
  801.  
  802.       byte[] var2 = new byte[var0.length - var1];
  803.  
  804.       for(int var3 = var1; var3 < var0.length; ++var3) {
  805.          var2[var3 - var1] = var0[var3];
  806.       }
  807.  
  808.       return var2;
  809.    }
  810.  
  811.    private static byte[] makePositive(byte[] var0) {
  812.       int var1;
  813.       for(var1 = 0; var1 < var0.length && var0[var1] == -1; ++var1) {
  814.       }
  815.  
  816.       int var2;
  817.       for(var2 = var1; var2 < var0.length && var0[var2] == 0; ++var2) {
  818.       }
  819.  
  820.       int var3 = var2 == var0.length ? 1 : 0;
  821.       byte[] var4 = new byte[var0.length - var1 + var3];
  822.  
  823.       for(int var5 = var1; var5 < var0.length; ++var5) {
  824.          var4[var5 - var1 + var3] = (byte)(~var0[var5]);
  825.       }
  826.  
  827.       for(int var6 = var4.length - 1; ++var4[var6] == 0; --var6) {
  828.       }
  829.  
  830.       return var4;
  831.    }
  832.  
  833.    private int byteLength() {
  834.       return this.bitLength() / 8 + 1;
  835.    }
  836.  
  837.    private int signBit() {
  838.       return this.signum < 0 ? 1 : 0;
  839.    }
  840.  
  841.    private byte signByte() {
  842.       return (byte)(this.signum < 0 ? -1 : 0);
  843.    }
  844.  
  845.    private byte getByte(int var1) {
  846.       if (var1 >= this.magnitude.length) {
  847.          return this.signByte();
  848.       } else {
  849.          byte var2 = this.magnitude[this.magnitude.length - var1 - 1];
  850.          return (byte)(this.signum >= 0 ? var2 : (var1 <= this.firstNonzeroByteNum() ? -var2 : ~var2));
  851.       }
  852.    }
  853.  
  854.    private int firstNonzeroByteNum() {
  855.       if (this.firstNonzeroByteNum == -2) {
  856.          int var1;
  857.          for(var1 = this.magnitude.length - 1; var1 >= 0 && this.magnitude[var1] == 0; --var1) {
  858.          }
  859.  
  860.          this.firstNonzeroByteNum = this.magnitude.length - var1 - 1;
  861.       }
  862.  
  863.       return this.firstNonzeroByteNum;
  864.    }
  865.  
  866.    private static native void plumbInit();
  867.  
  868.    private static native byte[] plumbAdd(byte[] var0, byte[] var1);
  869.  
  870.    private static native BigInteger plumbSubtract(byte[] var0, byte[] var1);
  871.  
  872.    private static native byte[] plumbMultiply(byte[] var0, byte[] var1);
  873.  
  874.    private static native byte[] plumbDivide(byte[] var0, byte[] var1);
  875.  
  876.    private static native byte[] plumbRemainder(byte[] var0, byte[] var1);
  877.  
  878.    private static native byte[][] plumbDivideAndRemainder(byte[] var0, byte[] var1);
  879.  
  880.    private static native byte[] plumbGcd(byte[] var0, byte[] var1);
  881.  
  882.    private static native byte[] plumbModPow(byte[] var0, byte[] var1, byte[] var2);
  883.  
  884.    private static native byte[] plumbModInverse(byte[] var0, byte[] var1);
  885.  
  886.    private static native byte[] plumbSquare(byte[] var0);
  887.  
  888.    private static native byte[] plumbGeneratePrime(byte[] var0);
  889.  
  890.    static {
  891.       for(int var0 = 1; var0 <= 16; ++var0) {
  892.          byte[] var1 = new byte[]{(byte)var0};
  893.          posConst[var0] = new BigInteger(var1, 1);
  894.          negConst[var0] = new BigInteger(var1, -1);
  895.       }
  896.  
  897.       bitLen = new byte[]{0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
  898.       bitCnt = new byte[]{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
  899.       trailingZeroCnt = new byte[]{8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
  900.       zeros = new String[64];
  901.       zeros[63] = "000000000000000000000000000000000000000000000000000000000000000";
  902.  
  903.       for(int var2 = 0; var2 < 63; ++var2) {
  904.          zeros[var2] = zeros[63].substring(0, var2);
  905.       }
  906.  
  907.       System.loadLibrary("math");
  908.       plumbInit();
  909.       ONE = valueOf(1L);
  910.       TWO = valueOf(2L);
  911.       ZERO_CHAR = Character.forDigit(0, 2);
  912.       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};
  913.       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)};
  914.    }
  915. }
  916.