zoukankan      html  css  js  c++  java
  • 大数的四则运算JAVA源码

    /*
     * Copyright (c) 2006, <a href="http://lib.csdn.net/base/oracle" class='replace_word' title="Oracle知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Oracle</a> and/or its affiliates. All rights reserved.
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     */
    /*
     * %W% %E%
     */
    package <a href="http://lib.csdn.net/base/javaee" class='replace_word' title="Java EE知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>.math;
    import java.util.Random;
    import java.io.*;
    /**
     * Immutable arbitrary-precision integers.  All operations behave as if
     * BigIntegers were represented in two's-complement notation (like Java's
     * primitive integer types).  BigInteger provides analogues to all of Java's
     * primitive integer operators, and all relevant methods from java.lang.Math.
     * Additionally, BigInteger provides operations for modular arithmetic, GCD
     * calculation, primality testing, prime generation, bit manipulation,
     * and a few other miscellaneous operations.
     * <p>
     * Semantics of arithmetic operations exactly mimic those of Java's integer
     * arithmetic operators, as defined in <i>The <a href="http://lib.csdn.net/base/java" class='replace_word' title="Java 知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Java </a>Language Specification</i>.
     * For example, division by zero throws an {@code ArithmeticException}, and
     * division of a negative by a positive yields a negative (or zero) remainder.
     * All of the details in the Spec concerning overflow are ignored, as
     * BigIntegers are made as large as necessary to accommodate the results of an
     * operation.
     * <p>
     * Semantics of shift operations extend those of Java's shift operators
     * to allow for negative shift distances.  A right-shift with a negative
     * shift distance results in a left shift, and vice-versa.  The unsigned
     * right shift operator ({@code >>>}) is omitted, as this operation makes
     * little sense in combination with the "infinite word size" abstraction
     * provided by this class.
     * <p>
     * Semantics of bitwise logical operations exactly mimic those of Java's
     * bitwise integer operators.  The binary operators ({@code and},
     * {@code or}, {@code xor}) implicitly perform sign extension on the shorter
     * of the two operands prior to performing the operation.
     * <p>
     * Comparison operations perform signed integer comparisons, analogous to
     * those performed by Java's relational and equality operators.
     * <p>
     * Modular arithmetic operations are provided to compute residues, perform
     * exponentiation, and compute multiplicative inverses.  These methods always
     * return a non-negative result, between {@code 0} and {@code (modulus - 1)},
     * inclusive.
     * <p>
     * Bit operations operate on a single bit of the two's-complement
     * representation of their operand.  If necessary, the operand is sign-
     * extended so that it contains the designated bit.  None of the single-bit
     * operations can produce a BigInteger with a different sign from the
     * BigInteger being operated on, as they affect only a single bit, and the
     * "infinite word size" abstraction provided by this class ensures that there
     * are infinitely many "virtual sign bits" preceding each BigInteger.
     * <p>
     * For the sake of brevity and clarity, pseudo-code is used throughout the
     * descriptions of BigInteger methods.  The pseudo-code expression
     * {@code (i + j)} is shorthand for "a BigInteger whose value is
     * that of the BigInteger {@code i} plus that of the BigInteger {@code j}."
     * The pseudo-code expression {@code (i == j)} is shorthand for
     * "{@code true} if and only if the BigInteger {@code i} represents the same
     * value as the BigInteger {@code j}."  Other pseudo-code expressions are
     * interpreted similarly.
     * <p>
     * All methods and constructors in this class throw
     * {@code NullPointerException} when passed
     * a null object reference for any input parameter.
     *
     * @see     BigDecimal
     * @author  Josh Bloch
     * @author  Michael McCloskey
     * @since JDK1.1
     */
    public class BigInteger extends Number implements Comparable<BigInteger> {
        /**
         * The signum of this BigInteger: -1 for negative, 0 for zero, or
         * 1 for positive.  Note that the BigInteger zero <i>must</i> have
         * a signum of 0.  This is necessary to ensures that there is exactly one
         * representation for each BigInteger value.
         *
         * @serial
         */
        final int signum;
        /**
         * The magnitude of this BigInteger, in <i>big-endian</i> order: the
         * zeroth element of this array is the most-significant int of the
         * magnitude.  The magnitude must be "minimal" in that the most-significant
         * int ({@code mag[0]}) must be non-zero.  This is necessary to
         * ensure that there is exactly one representation for each BigInteger
         * value.  Note that this implies that the BigInteger zero has a
         * zero-length mag array.
         */
        final int[] mag;
        // These "redundant fields" are initialized with recognizable nonsense
        // values, and cached the first time they are needed (or never, if they
        // aren't needed).
        /**
         * One plus the bitCount of this BigInteger. Zeros means unitialized.
         *
         * @serial
         * @see #bitCount
         * @deprecated Deprecated since logical value is offset from stored 
         * value and correction factor is applied in accessor method.
         */
        @Deprecated
        private int bitCount;
        
        /**
         * One plus the bitLength of this BigInteger. Zeros means unitialized. 
         * (either value is acceptable).
         *
         * @serial
         * @see #bitLength()
         * @deprecated Deprecated since logical value is offset from stored 
         * value and correction factor is applied in accessor method.
         */
        @Deprecated
        private int bitLength;
        /**
         * Two plus the lowest set bit of this BigInteger, as returned by 
         * getLowestSetBit().
         *
         * @serial
         * @see #getLowestSetBit
         * @deprecated Deprecated since logical value is offset from stored 
         * value and correction factor is applied in accessor method.
         */
        @Deprecated
        private int lowestSetBit;
        /**
         * Two plus the index of the lowest-order int in the magnitude of this 
         * BigInteger that contains a nonzero int, or -2 (either value is acceptable).
         * The least significant int has int-number 0, the next int in order of 
         * increasing significance has int-number 1, and so forth.
         * @deprecated Deprecated since logical value is offset from stored 
         * value and correction factor is applied in accessor method.
         */
        @Deprecated
        private int firstNonzeroIntNum;
        /**
         * This mask is used to obtain the value of an int as if it were unsigned.
         */
        final static long LONG_MASK = 0xffffffffL;
        
        //Constructors
        /**
         * Translates a byte array containing the two's-complement binary
         * representation of a BigInteger into a BigInteger.  The input array is
         * assumed to be in <i>big-endian</i> byte-order: the most significant
         * byte is in the zeroth element.
         *
         * @param  val big-endian two's-complement binary representation of
         *           BigInteger.
         * @throws NumberFormatException {@code val} is zero bytes long.
         */
        public BigInteger(byte[] val) {
        if (val.length == 0)
            throw new NumberFormatException("Zero length BigInteger");
        if (val[0] < 0) {
                mag = makePositive(val);
            signum = -1;
        } else {
            mag = stripLeadingZeroBytes(val);
            signum = (mag.length == 0 ? 0 : 1);
        }
        }
        /**
         * This private constructor translates an int array containing the
         * two's-complement binary representation of a BigInteger into a
         * BigInteger. The input array is assumed to be in <i>big-endian</i>
         * int-order: the most significant int is in the zeroth element.
         */
        private BigInteger(int[] val) {
        if (val.length == 0)
            throw new NumberFormatException("Zero length BigInteger");
        if (val[0] < 0) {
                mag = makePositive(val);
            signum = -1;
        } else {
            mag = trustedStripLeadingZeroInts(val);
            signum = (mag.length == 0 ? 0 : 1);
        }
        }
        /**
         * Translates the sign-magnitude representation of a BigInteger into a
         * BigInteger.  The sign is represented as an integer signum value: -1 for
         * negative, 0 for zero, or 1 for positive.  The magnitude is a byte array
         * in <i>big-endian</i> byte-order: the most significant byte is in the
         * zeroth element.  A zero-length magnitude array is permissible, and will
         * result in a BigInteger value of 0, whether signum is -1, 0 or 1.
         *
         * @param  signum signum of the number (-1 for negative, 0 for zero, 1
         *            for positive).
         * @param  magnitude big-endian binary representation of the magnitude of
         *            the number.
         * @throws NumberFormatException {@code signum} is not one of the three
         *           legal values (-1, 0, and 1), or {@code signum} is 0 and
         *           {@code magnitude} contains one or more non-zero bytes.
         */
        public BigInteger(int signum, byte[] magnitude) {
        this.mag = stripLeadingZeroBytes(magnitude);
        if (signum < -1 || signum > 1)
            throw(new NumberFormatException("Invalid signum value"));
        if (this.mag.length==0) {
            this.signum = 0;
        } else {
            if (signum == 0)
            throw(new NumberFormatException("signum-magnitude mismatch"));
            this.signum = signum;
        }
        }
        /**
         * A constructor for internal use that translates the sign-magnitude
         * representation of a BigInteger into a BigInteger. It checks the
         * arguments and copies the magnitude so this constructor would be
         * safe for external use.
         */
        private BigInteger(int signum, int[] magnitude) {
        this.mag = stripLeadingZeroInts(magnitude);
        if (signum < -1 || signum > 1)
            throw(new NumberFormatException("Invalid signum value"));
        if (this.mag.length==0) {
            this.signum = 0;
        } else {
            if (signum == 0)
            throw(new NumberFormatException("signum-magnitude mismatch"));
            this.signum = signum;
        }
        }
        /**
         * Translates the String representation of a BigInteger in the specified
         * radix into a BigInteger.  The String representation consists of an
         * optional minus sign followed by a sequence of one or more digits in the
         * specified radix.  The character-to-digit mapping is provided by
         * {@code Character.digit}.  The String may not contain any extraneous
         * characters (whitespace, for example).
         *
         * @param val String representation of BigInteger.
         * @param radix radix to be used in interpreting {@code val}.
         * @throws NumberFormatException {@code val} is not a valid representation
         *           of a BigInteger in the specified radix, or {@code radix} is
         *           outside the range from {@link Character#MIN_RADIX} to
         *           {@link Character#MAX_RADIX}, inclusive.
         * @see    Character#digit
         */
        public BigInteger(String val, int radix) {
        int cursor = 0, numDigits;
            int len = val.length();
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            throw new NumberFormatException("Radix out of range");
        if (val.length() == 0)
            throw new NumberFormatException("Zero length BigInteger");
        // Check for minus sign
            int sign = 1;
            int index = val.lastIndexOf("-");
            if (index != -1) {
                if (index == 0) {
                    if (val.length() == 1)
                        throw new NumberFormatException("Zero length BigInteger");
                    sign = -1;
                    cursor = 1;
                } else {
                    throw new NumberFormatException("Illegal embedded minus sign");
                }
            }
            // Skip leading zeros and compute number of digits in magnitude
        while (cursor < len &&
                   Character.digit(val.charAt(cursor), radix) == 0)
            cursor++;
        if (cursor == len) {
            mag = ZERO.mag;
                signum = 0;
            return;
        } 
            
            numDigits = len - cursor;
        signum = sign;
            // Pre-allocate array of expected size. May be too large but can
            // never be too small. Typically exact.
            int numBits = (int)(((numDigits * bitsPerDigit[radix]) >>> 10) + 1);
            int numWords = (numBits + 31) >>> 5;
            int[] magnitude = new int[numWords];
        // Process first (potentially short) digit group
        int firstGroupLen = numDigits % digitsPerInt[radix];
        if (firstGroupLen == 0)
            firstGroupLen = digitsPerInt[radix];
        String group = val.substring(cursor, cursor += firstGroupLen);
            magnitude[magnitude.length - 1] = Integer.parseInt(group, radix);
        if (magnitude[magnitude.length - 1] < 0)
            throw new NumberFormatException("Illegal digit");
            
        // Process remaining digit groups
            int superRadix = intRadix[radix];
            int groupVal = 0;
        while (cursor < val.length()) {
            group = val.substring(cursor, cursor += digitsPerInt[radix]);
            groupVal = Integer.parseInt(group, radix);
            if (groupVal < 0)
            throw new NumberFormatException("Illegal digit");
                destructiveMulAdd(magnitude, superRadix, groupVal);
        }
            // Required for cases where the array was overallocated.
            mag = trustedStripLeadingZeroInts(magnitude);
        }
        // Constructs a new BigInteger using a char array with radix=10
        BigInteger(char[] val) {
            int cursor = 0, numDigits;
            int len = val.length;
        // Check for leading minus sign
        int sign = 1;
        if (val[0] == '-') {
            if (len == 1)
            throw new NumberFormatException("Zero length BigInteger");
            sign = -1;
            cursor = 1;
        }
            
            // Skip leading zeros and compute number of digits in magnitude
        while (cursor < len && Character.digit(val[cursor], 10) == 0)
            cursor++;
        if (cursor == len) {
            signum = 0;
            mag = ZERO.mag;
            return;
        }
            
            numDigits = len - cursor;
            signum = sign;
            
            // Pre-allocate array of expected size
            int numWords;
            if (len < 10) {
                numWords = 1;
            } else {    
                int numBits = (int)(((numDigits * bitsPerDigit[10]) >>> 10) + 1);
                numWords = (numBits + 31) >>> 5;
            }
            
            int magnitude[] = new int[numWords];
     
        // Process first (potentially short) digit group
        int firstGroupLen = numDigits % digitsPerInt[10];
        if (firstGroupLen == 0)
            firstGroupLen = digitsPerInt[10];
            magnitude[numWords - 1] = parseInt(val, cursor,  cursor += firstGroupLen);
            
        // Process remaining digit groups
        while (cursor < len) {
            int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]);
                destructiveMulAdd(magnitude, intRadix[10], groupVal);
        }
            mag = trustedStripLeadingZeroInts(magnitude);
        }
        // Create an integer with the digits between the two indexes
        // Assumes start < end. The result may be negative, but it
        // is to be treated as an unsigned value.
        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));
            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;
        }
        // bitsPerDigit in the given radix times 1024
        // Rounded up to avoid underallocation.
        private static long bitsPerDigit[] = { 0, 0,
            1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
            3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
            4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
                                               5253, 5295};
        // Multiply x array times word y in place, and add word z
        private static void destructiveMulAdd(int[] x, int y, int z) {
            // Perform the multiplication word by word
            long ylong = y & LONG_MASK;
            long zlong = z & LONG_MASK;
            int len = x.length;
            long product = 0;
            long carry = 0;
            for (int i = len-1; i >= 0; i--) {
                product = ylong * (x[i] & LONG_MASK) + carry;
                x[i] = (int)product;
                carry = product >>> 32;
            }
            // Perform the addition
            long sum = (x[len-1] & LONG_MASK) + zlong;
            x[len-1] = (int)sum;
            carry = sum >>> 32;
            for (int i = len-2; i >= 0; i--) {
                sum = (x[i] & LONG_MASK) + carry;
                x[i] = (int)sum;
                carry = sum >>> 32;
            }
        }
        /**
         * Translates the decimal String representation of a BigInteger into a
         * BigInteger.  The String representation consists of an optional minus
         * sign followed by a sequence of one or more decimal digits.  The
         * character-to-digit mapping is provided by {@code Character.digit}.
         * The String may not contain any extraneous characters (whitespace, for
         * example).
         *
         * @param val decimal String representation of BigInteger.
         * @throws NumberFormatException {@code val} is not a valid representation
         *           of a BigInteger.
         * @see    Character#digit
         */
        public BigInteger(String val) {
        this(val, 10);
        }
        /**
         * Constructs a randomly generated BigInteger, uniformly distributed over
         * the range {@code 0} to (2<sup>{@code numBits}</sup> - 1), inclusive.
         * The uniformity of the distribution assumes that a fair source of random
         * bits is provided in {@code rnd}.  Note that this constructor always
         * constructs a non-negative BigInteger.
         *
         * @param  numBits maximum bitLength of the new BigInteger.
         * @param  rnd source of randomness to be used in computing the new
         *           BigInteger.
         * @throws IllegalArgumentException {@code numBits} is negative.
         * @see #bitLength()
         */
        public BigInteger(int numBits, Random rnd) {
        this(1, randomBits(numBits, rnd));
        }
        private static byte[] randomBits(int numBits, Random rnd) {
        if (numBits < 0)
            throw new IllegalArgumentException("numBits must be non-negative");
        int numBytes = (int)(((long)numBits+7)/8); // avoid overflow
        byte[] randomBits = new byte[numBytes];
        // Generate random bytes and mask out any excess bits
        if (numBytes > 0) {
            rnd.nextBytes(randomBits);
            int excessBits = 8*numBytes - numBits;
            randomBits[0] &= (1 << (8-excessBits)) - 1;
        }
        return randomBits;
        }
        /**
         * Constructs a randomly generated positive BigInteger that is probably
         * prime, with the specified bitLength.<p>
         *
         * It is recommended that the {@link #probablePrime probablePrime}
         * method be used in preference to this constructor unless there
         * is a compelling need to specify a certainty.
         *
         * @param  bitLength bitLength of the returned BigInteger.
         * @param  certainty a measure of the uncertainty that the caller is
         *         willing to tolerate.  The probability that the new BigInteger
         *           represents a prime number will exceed
         *           (1 - 1/2<sup>{@code certainty}</sup>).  The execution time of
         *           this constructor is proportional to the value of this parameter.
         * @param  rnd source of random bits used to select candidates to be
         *           tested for primality.
         * @throws ArithmeticException {@code bitLength < 2}.
         * @see    #bitLength()
         */
        public BigInteger(int bitLength, int certainty, Random rnd) {
            BigInteger prime;
        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");
            // The cutoff of 95 was chosen empirically for best performance
            prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd)
                                    : largePrime(bitLength, certainty, rnd));
        signum = 1;
        mag = prime.mag;
        }
        // Minimum size in bits that the requested prime number has
        // before we use the large prime number generating algorithms
        private static final int SMALL_PRIME_THRESHOLD = 95;
        // Certainty required to meet the spec of probablePrime
        private static final int DEFAULT_PRIME_CERTAINTY = 100;
        /**
         * Returns a positive BigInteger that is probably prime, with the
         * specified bitLength. The probability that a BigInteger returned
         * by this method is composite does not exceed 2<sup>-100</sup>.
         *
         * @param  bitLength bitLength of the returned BigInteger.
         * @param  rnd source of random bits used to select candidates to be
         *           tested for primality.
         * @return a BigInteger of {@code bitLength} bits that is probably prime
         * @throws ArithmeticException {@code bitLength < 2}.
         * @see    #bitLength()
         * @since 1.4
         */
        public static BigInteger probablePrime(int bitLength, Random rnd) {
        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");
            // The cutoff of 95 was chosen empirically for best performance
            return (bitLength < SMALL_PRIME_THRESHOLD ?
                    smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
                    largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
        }
        /**
         * Find a random number of the specified bitLength that is probably prime.
         * This method is used for smaller primes, its performance degrades on
         * larger bitlengths.
         *
         * This method assumes bitLength > 1.
         */
        private static BigInteger smallPrime(int bitLength, int certainty, Random rnd) {
            int magLen = (bitLength + 31) >>> 5;
            int temp[] = new int[magLen];
            int highBit = 1 << ((bitLength+31) & 0x1f);  // High bit of high int
            int highMask = (highBit << 1) - 1;  // Bits to keep in high int
            while(true) {
                // Construct a candidate
                for (int i=0; i<magLen; i++)
                    temp[i] = rnd.nextInt();
                temp[0] = (temp[0] & highMask) | highBit;  // Ensure exact length
                if (bitLength > 2)
                    temp[magLen-1] |= 1;  // Make odd if bitlen > 2
                BigInteger p = new BigInteger(temp, 1);
                // Do cheap "pre-test" if applicable
                if (bitLength > 6) {
                    long r = p.remainder(SMALL_PRIME_PRODUCT).longValue();
                    if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) || 
                        (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) || 
                        (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0))
                        continue; // Candidate is composite; try another
                }
                
                // All candidates of bitLength 2 and 3 are prime by this point
                if (bitLength < 4)
                    return p;
                // Do expensive test if we survive pre-test (or it's inapplicable)
                if (p.primeToCertainty(certainty, rnd))
                    return p;
            }
        }
        private static final BigInteger SMALL_PRIME_PRODUCT
                           = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41);
        /**
         * Find a random number of the specified bitLength that is probably prime.
         * This method is more appropriate for larger bitlengths since it uses
         * a sieve to eliminate most composites before using a more expensive
         * test.
         */
        private static BigInteger largePrime(int bitLength, int certainty, Random rnd) {
            BigInteger p;
            p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
            p.mag[p.mag.length-1] &= 0xfffffffe;
            // Use a sieve length likely to contain the next prime number
            int searchLen = (bitLength / 20) * 64;
            BitSieve searchSieve = new BitSieve(p, searchLen);
            BigInteger candidate = searchSieve.retrieve(p, certainty, rnd);
            while ((candidate == null) || (candidate.bitLength() != bitLength)) {
                p = p.add(BigInteger.valueOf(2*searchLen));
                if (p.bitLength() != bitLength)
                    p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
                p.mag[p.mag.length-1] &= 0xfffffffe;
                searchSieve = new BitSieve(p, searchLen);
                candidate = searchSieve.retrieve(p, certainty, rnd);
            }
            return candidate;
        }
       /**
        * Returns the first integer greater than this {@code BigInteger} that
        * is probably prime.  The probability that the number returned by this
        * method is composite does not exceed 2<sup>-100</sup>. This method will
        * never skip over a prime when searching: if it returns {@code p}, there
        * is no prime {@code q} such that {@code this < q < p}.
        *
        * @return the first integer greater than this {@code BigInteger} that
        *         is probably prime.
        * @throws ArithmeticException {@code this < 0}.
        * @since 1.5
        */
        public BigInteger nextProbablePrime() {
            if (this.signum < 0)
                throw new ArithmeticException("start < 0: " + this);
            
            // Handle trivial cases
            if ((this.signum == 0) || this.equals(ONE))
                return TWO;
            BigInteger result = this.add(ONE);
            // Fastpath for small numbers
            if (result.bitLength() < SMALL_PRIME_THRESHOLD) {
     
                // Ensure an odd number
                if (!result.testBit(0))
                    result = result.add(ONE);
                while(true) {
                    // Do cheap "pre-test" if applicable
                    if (result.bitLength() > 6) {
                        long r = result.remainder(SMALL_PRIME_PRODUCT).longValue();
                        if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) || 
                            (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) || 
                            (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) {
                            result = result.add(TWO);
                            continue; // Candidate is composite; try another
                        }
                    }
                
                    // All candidates of bitLength 2 and 3 are prime by this point
                    if (result.bitLength() < 4)
                        return result;
                    // The expensive test
                    if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY, null))
                        return result;
                    result = result.add(TWO);
                }
            }
            // Start at previous even number
            if (result.testBit(0))
                result = result.subtract(ONE);
            // Looking for the next large prime
            int searchLen = (result.bitLength() / 20) * 64;
            while(true) {
               BitSieve searchSieve = new BitSieve(result, searchLen);
               BigInteger candidate = searchSieve.retrieve(result,
                             DEFAULT_PRIME_CERTAINTY, null);
               if (candidate != null)
                   return candidate;
               result = result.add(BigInteger.valueOf(2 * searchLen));
            }
        }
        /**
         * Returns {@code true} if this BigInteger is probably prime,
         * {@code false} if it's definitely composite.
         *
         * This method assumes bitLength > 2.
         *
         * @param  certainty a measure of the uncertainty that the caller is
         *           willing to tolerate: if the call returns {@code true}
         *           the probability that this BigInteger is prime exceeds
         *           {@code (1 - 1/2<sup>certainty</sup>)}.  The execution time of
         *            this method is proportional to the value of this parameter.
         * @return {@code true} if this BigInteger is probably prime,
         *            {@code false} if it's definitely composite.
         */
        boolean primeToCertainty(int certainty, Random random) {
            int rounds = 0;
            int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;
            // The relationship between the certainty and the number of rounds
            // we perform is given in the draft standard ANSI X9.80, "PRIME
            // NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".
            int sizeInBits = this.bitLength();
            if (sizeInBits < 100) {
                rounds = 50;
                rounds = n < rounds ? n : rounds;
                return passesMillerRabin(rounds, random);
            }
            if (sizeInBits < 256) {
                rounds = 27;
            } else if (sizeInBits < 512) {
                rounds = 15;
            } else if (sizeInBits < 768) {
                rounds = 8;
            } else if (sizeInBits < 1024) {
                rounds = 4;
            } else {
                rounds = 2;
            }
            rounds = n < rounds ? n : rounds;
            return passesMillerRabin(rounds, random) && passesLucasLehmer();
        }
        /**
         * Returns true iff this BigInteger is a Lucas-Lehmer probable prime.
         *
         * The following assumptions are made:
         * This BigInteger is a positive, odd number.
         */
        private boolean passesLucasLehmer() {
            BigInteger thisPlusOne = this.add(ONE);
            // Step 1
            int d = 5;
            while (jacobiSymbol(d, this) != -1) {
                // 5, -7, 9, -11, ...
                d = (d<0) ? Math.abs(d)+2 : -(d+2);
            }
            
            // Step 2
            BigInteger u = lucasLehmerSequence(d, thisPlusOne, this);
            // Step 3
            return u.mod(this).equals(ZERO);
        }
        /**
         * Computes Jacobi(p,n).
         * Assumes n positive, odd, n>=3.
         */
        private static int jacobiSymbol(int p, BigInteger n) {
            if (p == 0)
                return 0;
            // Algorithm and comments adapted from Colin Plumb's C library.
        int j = 1;
        int u = n.mag[n.mag.length-1];
            // Make p positive
            if (p < 0) {
                p = -p;
                int n8 = u & 7;
                if ((n8 == 3) || (n8 == 7))
                    j = -j; // 3 (011) or 7 (111) mod 8
            }
        // Get rid of factors of 2 in p
        while ((p & 3) == 0)
                p >>= 2;
        if ((p & 1) == 0) {
                p >>= 1;
                if (((u ^ (u>>1)) & 2) != 0)
                    j = -j;    // 3 (011) or 5 (101) mod 8
        }
        if (p == 1)
            return j;
        // Then, apply quadratic reciprocity
        if ((p & u & 2) != 0)    // p = u = 3 (mod 4)?
            j = -j;
        // And reduce u mod p
        u = n.mod(BigInteger.valueOf(p)).intValue();
        // Now compute Jacobi(u,p), u < p
        while (u != 0) {
                while ((u & 3) == 0)
                    u >>= 2;
                if ((u & 1) == 0) {
                    u >>= 1;
                    if (((p ^ (p>>1)) & 2) != 0)
                        j = -j;    // 3 (011) or 5 (101) mod 8
                }
                if (u == 1)
                    return j;
                // Now both u and p are odd, so use quadratic reciprocity
                assert (u < p);
                int t = u; u = p; p = t;
                if ((u & p & 2) != 0) // u = p = 3 (mod 4)?
                    j = -j;
                // Now u >= p, so it can be reduced
                u %= p;
        }
        return 0;
        }
        private static BigInteger lucasLehmerSequence(int z, BigInteger k, BigInteger n) {
            BigInteger d = BigInteger.valueOf(z);
            BigInteger u = ONE; BigInteger u2;
            BigInteger v = ONE; BigInteger v2;
            for (int i=k.bitLength()-2; i>=0; i--) {
                u2 = u.multiply(v).mod(n);
                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 = u.add(v).mod(n);
                    if (u2.testBit(0)) 
                        u2 = u2.subtract(n);
          
                    u2 = u2.shiftRight(1);          
                    v2 = v.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 volatile Random staticRandom;
        private static Random getSecureRandom() {
        if (staticRandom == null) {
            staticRandom = new java.security.SecureRandom();
        }
        return staticRandom;
        }
        /**
         * Returns true iff this BigInteger passes the specified number of
         * Miller-Rabin tests. This test is taken from the DSA spec (NIST FIPS
         * 186-2).
         *
         * The following assumptions are made:
         * This BigInteger is a positive, odd number greater than 2.
         * iterations<=50.
         */
        private boolean passesMillerRabin(int iterations, Random rnd) {
        // Find a and m such that m is odd and this == 1 + 2**a * m
            BigInteger thisMinusOne = this.subtract(ONE);
        BigInteger m = thisMinusOne;
        int a = m.getLowestSetBit();
        m = m.shiftRight(a);
        // Do the tests
        if (rnd == null) {
            rnd = getSecureRandom();
        }
        for (int i=0; i<iterations; i++) {
            // Generate a uniform random on (1, this)
            BigInteger b;
            do {
            b = new BigInteger(this.bitLength(), rnd);
            } while (b.compareTo(ONE) <= 0 || b.compareTo(this) >= 0);
            int j = 0;
            BigInteger z = b.modPow(m, this);
            while(!((j==0 && z.equals(ONE)) || z.equals(thisMinusOne))) {
            if (j>0 && z.equals(ONE) || ++j==a)
                return false;
            z = z.modPow(TWO, this);
            }
        }
        return true;
        }
        /**
         * This internal constructor differs from its public cousin
         * with the arguments reversed in two ways: it assumes that its
         * arguments are correct, and it doesn't copy the magnitude array.
         */
        BigInteger(int[] magnitude, int signum) {
        this.signum = (magnitude.length==0 ? 0 : signum);
        this.mag = magnitude;
        }
        /**
         * This private constructor is for internal use and assumes that its
         * arguments are correct.
         */
        private BigInteger(byte[] magnitude, int signum) {
        this.signum = (magnitude.length==0 ? 0 : signum);
            this.mag = stripLeadingZeroBytes(magnitude);
        }
        //Static Factory Methods
        /**
         * Returns a BigInteger whose value is equal to that of the
         * specified {@code long}.  This "static factory method" is
         * provided in preference to a ({@code long}) constructor
         * because it allows for reuse of frequently used BigIntegers.
         *
         * @param  val value of the BigInteger to return.
         * @return a BigInteger with the specified value.
         */
        public static BigInteger valueOf(long val) {
        // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
        if (val == 0)
            return ZERO;
        if (val > 0 && val <= MAX_CONSTANT)
            return posConst[(int) val];
        else if (val < 0 && val >= -MAX_CONSTANT)
            return negConst[(int) -val];
        return new BigInteger(val);
        }
        /**
         * Constructs a BigInteger with the specified value, which may not be zero.
         */
        private BigInteger(long val) {
            if (val < 0) {
                val = -val;
                signum = -1;
            } else {
                signum = 1;
            }
            int highWord = (int)(val >>> 32);
            if (highWord==0) {
                mag = new int[1];
                mag[0] = (int)val;
            } else {
                mag = new int[2];
                mag[0] = highWord;
                mag[1] = (int)val;
            }
        }
        /**
         * Returns a BigInteger with the given two's complement representation.
         * Assumes that the input array will not be modified (the returned
         * BigInteger will reference the input array if feasible).
         */
        private static BigInteger valueOf(int val[]) {
            return (val[0]>0 ? new BigInteger(val, 1) : new BigInteger(val));
        }
        // Constants
        /**
         * Initialize static constant array when class is loaded.
         */
        private final static int MAX_CONSTANT = 16;
        private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];
        private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];
        static {
        for (int i = 1; i <= MAX_CONSTANT; i++) {
            int[] magnitude = new int[1];
            magnitude[0] = i;
            posConst[i] = new BigInteger(magnitude,  1);
            negConst[i] = new BigInteger(magnitude, -1);
        }
        }
        /**
         * The BigInteger constant zero.
         *
         * @since   1.2
         */
        public static final BigInteger ZERO = new BigInteger(new int[0], 0);
        /**
         * The BigInteger constant one.
         *
         * @since   1.2
         */
        public static final BigInteger ONE = valueOf(1);
        /**
         * The BigInteger constant two.  (Not exported.)
         */
        private static final BigInteger TWO = valueOf(2);
        /**
         * The BigInteger constant ten.
         *
         * @since   1.5
         */
        public static final BigInteger TEN = valueOf(10);
        // Arithmetic Operations
        /**
         * Returns a BigInteger whose value is {@code (this + val)}.
         *
         * @param  val value to be added to this BigInteger.
         * @return {@code this + val}
         */
        public BigInteger add(BigInteger val) {
        if (val.signum == 0)
                return this;
        if (signum == 0)
            return val;
        if (val.signum == signum)
                return new BigInteger(add(mag, val.mag), signum);
            int cmp = compareMagnitude(val);
            if (cmp==0)
                return ZERO;
            int[] resultMag = (cmp>0 ? subtract(mag, val.mag) : 
                               subtract(val.mag, mag));
            resultMag = trustedStripLeadingZeroInts(resultMag);
            return new BigInteger(resultMag, cmp == signum ? 1 : -1);
        }
        
        /**
         * Adds the contents of the int arrays x and y. This method allocates
         * a new int array to hold the answer and returns a reference to that
         * array.
         */
        private static int[] add(int[] x, int[] y) {
            // If x is shorter, swap the two arrays
            if (x.length < y.length) {
                int[] tmp = x;
                x = y;
                y = tmp;
            }
            int xIndex = x.length;
            int yIndex = y.length;
            int result[] = new int[xIndex];
            long sum = 0;
            // Add common parts of both numbers
            while(yIndex > 0) {
                sum = (x[--xIndex] & LONG_MASK) + 
                      (y[--yIndex] & LONG_MASK) + (sum >>> 32);
                result[xIndex] = (int)sum;
            }
            // Copy remainder of longer number while carry propagation is required
            boolean carry = (sum >>> 32 != 0);
            while (xIndex > 0 && carry)
                carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
            // Copy remainder of longer number
            while (xIndex > 0)
                result[--xIndex] = x[xIndex];
            // Grow result if necessary
            if (carry) {
                int bigger[] = new int[result.length + 1];
                System.arraycopy(result, 0, bigger, 1, result.length);
                bigger[0] = 0x01;
                return bigger;
            }
            return result;
        }
        /**
         * Returns a BigInteger whose value is {@code (this - val)}.
         *
         * @param  val value to be subtracted from this BigInteger.
         * @return {@code this - val}
         */
        public BigInteger subtract(BigInteger val) {
        if (val.signum == 0)
                return this;
        if (signum == 0)
            return val.negate();
        if (val.signum != signum)
                return new BigInteger(add(mag, val.mag), signum);
            int cmp = compareMagnitude(val);
            if (cmp==0)
                return ZERO;
            int[] resultMag = (cmp>0 ? subtract(mag, val.mag)
                               : subtract(val.mag, mag));
            resultMag = trustedStripLeadingZeroInts(resultMag);
            return new BigInteger(resultMag, (cmp == signum) ? 1 : -1);
        }
        /**
         * Subtracts the contents of the second int arrays (little) from the
         * first (big).  The first int array (big) must represent a larger number
         * than the second.  This method allocates the space necessary to hold the
         * answer.
         */
        private static int[] subtract(int[] big, int[] little) {
            int bigIndex = big.length;
            int result[] = new int[bigIndex];
            int littleIndex = little.length;
            long difference = 0;
            // Subtract common parts of both numbers
            while(littleIndex > 0) {
                difference = (big[--bigIndex] & LONG_MASK) - 
                             (little[--littleIndex] & LONG_MASK) +
                             (difference >> 32);
                result[bigIndex] = (int)difference;
            }
            // Subtract remainder of longer number while borrow propagates
            boolean borrow = (difference >> 32 != 0);
            while (bigIndex > 0 && borrow)
                borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
            // Copy remainder of longer number
            while (bigIndex > 0)
                result[--bigIndex] = big[bigIndex];
            return result;
        }
        
        /**
         * Returns a BigInteger whose value is {@code (this * val)}.
         *
         * @param  val value to be multiplied by this BigInteger.
         * @return {@code this * val}
         */
        public BigInteger multiply(BigInteger val) {
            if (val.signum == 0 || signum == 0)
            return ZERO;
            int[] res = multiplyToLen(mag, mag.length, val.mag, val.mag.length, null);
            res = trustedStripLeadingZeroInts(res);
            return new BigInteger(res, signum == val.signum ? 1 : -1);
        }
        
        /**
         * Package private methods used by BigDecimal code to multiply a BigInteger 
         * with a long. Assumes v is not equal to INFLATED.
         */
        BigInteger multiply(long v) {
            if (v == 0 || signum == 0)
              return ZERO;
            assert v != BigDecimal.INFLATED;
            int rsign = (v > 0 ? signum : -signum);
            if (v < 0)
                v = -v;
            long dh = v >>> 32;      // higher order bits
            long dl = v & LONG_MASK; // lower order bits
            int xlen = mag.length;
            int[] value = mag;
            int[] rmag = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
            long carry = 0;
            int rstart = rmag.length - 1;
            for (int i = xlen - 1; i >= 0; i--) {
                long product = (value[i] & LONG_MASK) * dl + carry;
                rmag[rstart--] = (int)product;
                carry = product >>> 32;
            }
            rmag[rstart] = (int)carry;
            if (dh != 0L) {
                carry = 0;
                rstart = rmag.length - 2;
                for (int i = xlen - 1; i >= 0; i--) {
                    long product = (value[i] & LONG_MASK) * dh + 
                        (rmag[rstart] & LONG_MASK) + carry;
                    rmag[rstart--] = (int)product;
                    carry = product >>> 32;
                }
                rmag[0] = (int)carry;
            }
        if (carry == 0L)
            rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
            return new BigInteger(rmag, rsign);
        }
        /**
         * Multiplies int arrays x and y to the specified lengths and places
         * the result into z. There will be no leading zeros in the resultant array.
         */
        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 = 0;
            for (int j=ystart, k=ystart+1+xstart; j>=0; j--, k--) {
                long product = (y[j] & LONG_MASK) *
                               (x[xstart] & LONG_MASK) + carry;
                z[k] = (int)product;
                carry = product >>> 32;
            }
            z[xstart] = (int)carry;
            for (int i = xstart-1; i >= 0; i--) {
                carry = 0;
                for (int j=ystart, k=ystart+1+i; j>=0; j--, k--) {
                    long product = (y[j] & LONG_MASK) * 
                                   (x[i] & LONG_MASK) + 
                                   (z[k] & LONG_MASK) + carry;
                    z[k] = (int)product;
                    carry = product >>> 32;
                }
                z[i] = (int)carry;
            }
            return z;
        }
        /**
         * Returns a BigInteger whose value is {@code (this<sup>2</sup>)}.
         *
         * @return {@code this<sup>2</sup>}
         */
        private BigInteger square() {
            if (signum == 0)
            return ZERO;
            int[] z = squareToLen(mag, mag.length, null);
            return new BigInteger(trustedStripLeadingZeroInts(z), 1);
        }
        /**
         * Squares the contents of the int array x. The result is placed into the
         * int array z.  The contents of x are not changed.
         */
        private static final int[] squareToLen(int[] x, int len, int[] z) {
            /*
             * The algorithm used here is adapted from Colin Plumb's C library.
             * Technique: Consider the partial products in the multiplication
             * of "abcde" by itself:
             *
             *               a  b  c  d  e
             *            *  a  b  c  d  e
             *          ==================
             *              ae be ce de ee
             *           ad bd cd dd de
             *        ac bc cc cd ce
             *     ab bb bc bd be
             *  aa ab ac ad ae
             *
             * Note that everything above the main diagonal:
             *              ae be ce de = (abcd) * e
             *           ad bd cd       = (abc) * d
             *        ac bc             = (ab) * c
             *     ab                   = (a) * b
             *
             * is a copy of everything below the main diagonal:
             *                       de
             *                 cd ce
             *           bc bd be
             *     ab ac ad ae
             *
             * Thus, the sum is 2 * (off the diagonal) + diagonal.
             *
             * This is accumulated beginning with the diagonal (which
             * consist of the squares of the digits of the input), which is then
             * divided by two, the off-diagonal added, and multiplied by two
             * again.  The low bit is simply a copy of the low bit of the
             * input, so it doesn't need special care.
             */
            int zlen = len << 1;
            if (z == null || z.length < zlen)
                z = new int[zlen];
            
            // Store the squares, right shifted one bit (i.e., divided by 2)
            int lastProductLowWord = 0;
            for (int j=0, i=0; j<len; j++) {
                long piece = (x[j] & LONG_MASK);
                long product = piece * piece;
                z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
                z[i++] = (int)(product >>> 1);
                lastProductLowWord = (int)product;
            }
            // Add in off-diagonal sums
            for (int i=len, offset=1; i>0; i--, offset+=2) {
                int t = x[i-1];
                t = mulAdd(z, x, offset, i-1, t);
                addOne(z, offset-1, i, t);
            }
            // Shift back up and set low bit
            primitiveLeftShift(z, zlen, 1);
            z[zlen-1] |= x[len-1] & 1;
            return z;
        }
        /**
         * Returns a BigInteger whose value is {@code (this / val)}.
         *
         * @param  val value by which this BigInteger is to be divided.
         * @return {@code this / val}
         * @throws ArithmeticException {@code val==0}
         */
        public BigInteger divide(BigInteger val) {
            MutableBigInteger q = new MutableBigInteger(),
                              a = new MutableBigInteger(this.mag),
                              b = new MutableBigInteger(val.mag);
            a.divide(b, q);
            return q.toBigInteger(this.signum * val.signum);
        }
        /**
         * Returns an array of two BigIntegers containing {@code (this / val)}
         * followed by {@code (this % val)}.
         *
         * @param  val value by which this BigInteger is to be divided, and the
         *           remainder computed.
         * @return an array of two BigIntegers: the quotient {@code (this / val)}
         *           is the initial element, and the remainder {@code (this % val)}
         *           is the final element.
         * @throws ArithmeticException {@code val==0}
         */
        public BigInteger[] divideAndRemainder(BigInteger val) {
            BigInteger[] result = new BigInteger[2];
            MutableBigInteger q = new MutableBigInteger(),
                              a = new MutableBigInteger(this.mag),
                              b = new MutableBigInteger(val.mag);
            MutableBigInteger r = a.divide(b, q);
            result[0] = q.toBigInteger(this.signum * val.signum);
            result[1] = r.toBigInteger(this.signum);
            return result;
        }
        /**
         * Returns a BigInteger whose value is {@code (this % val)}.
         *
         * @param  val value by which this BigInteger is to be divided, and the
         *           remainder computed.
         * @return {@code this % val}
         * @throws ArithmeticException {@code val==0}
         */
        public BigInteger remainder(BigInteger val) {
            MutableBigInteger q = new MutableBigInteger(),
                              a = new MutableBigInteger(this.mag),
                              b = new MutableBigInteger(val.mag);
            return a.divide(b, q).toBigInteger(this.signum);
        }
        /**
         * Returns a BigInteger whose value is <tt>(this<sup>exponent</sup>)</tt>.
         * Note that {@code exponent} is an integer rather than a BigInteger.
         *
         * @param  exponent exponent to which this BigInteger is to be raised.
         * @return <tt>this<sup>exponent</sup></tt>
         * @throws ArithmeticException {@code exponent} is negative.  (This would
         *           cause the operation to yield a non-integer value.)
         */
        public BigInteger pow(int exponent) {
        if (exponent < 0)
            throw new ArithmeticException("Negative exponent");
        if (signum==0)
            return (exponent==0 ? ONE : this);
        // Perform exponentiation using repeated squaring trick
            int newSign = (signum<0 && (exponent&1)==1 ? -1 : 1);
        int[] baseToPow2 = this.mag;
            int[] result = {1};
        while (exponent != 0) {
            if ((exponent & 1)==1) {
            result = multiplyToLen(result, result.length, 
                                           baseToPow2, baseToPow2.length, null);
            result = trustedStripLeadingZeroInts(result);
            }
            if ((exponent >>>= 1) != 0) {
                    baseToPow2 = squareToLen(baseToPow2, baseToPow2.length, null);
            baseToPow2 = trustedStripLeadingZeroInts(baseToPow2);
            }
        }
        return new BigInteger(result, newSign);
        }
        /**
         * Returns a BigInteger whose value is the greatest common divisor of
         * {@code abs(this)} and {@code abs(val)}.  Returns 0 if
         * {@code this==0 && val==0}.
         *
         * @param  val value with which the GCD is to be computed.
         * @return {@code GCD(abs(this), abs(val))}
         */
        public BigInteger gcd(BigInteger val) {
            if (val.signum == 0)
            return this.abs();
        else if (this.signum == 0)
            return val.abs();
            MutableBigInteger a = new MutableBigInteger(this);
            MutableBigInteger b = new MutableBigInteger(val);
            MutableBigInteger result = a.hybridGCD(b);
            return result.toBigInteger(1);
        }
        /**
         * Package private method to return bit length for an integer.
         * 
         */
        static int bitLengthForInt(int n) {
            return 32 - Integer.numberOfLeadingZeros(n);
        }
        /**
         * Left shift int array a up to len by n bits. Returns the array that
         * results from the shift since space may have to be reallocated.
         */
        private static int[] leftShift(int[] a, int len, int n) {
            int nInts = n >>> 5;
            int nBits = n&0x1F;
            int bitsInHighWord = bitLengthForInt(a[0]);
            
            // If shift can be done without recopy, do so
            if (n <= (32-bitsInHighWord)) {
                primitiveLeftShift(a, len, nBits);
                return a;
            } else { // Array must be resized
                if (nBits <= (32-bitsInHighWord)) {
                    int result[] = new int[nInts+len];
                    for (int i=0; i<len; i++)
                        result[i] = a[i];
                    primitiveLeftShift(result, result.length, nBits);
                    return result;
                } else {
                    int result[] = new int[nInts+len+1];
                    for (int i=0; i<len; i++)
                        result[i] = a[i];
                    primitiveRightShift(result, result.length, 32 - nBits);
                    return result;
                }
            }
        }
        // shifts a up to len right n bits assumes no leading zeros, 0<n<32
        static void primitiveRightShift(int[] a, int len, int n) {
            int n2 = 32 - n;
            for (int i=len-1, c=a[i]; i>0; i--) {
                int b = c;
                c = a[i-1];
                a[i] = (c << n2) | (b >>> n);
            }
            a[0] >>>= n;
        }
        // shifts a up to len left n bits assumes no leading zeros, 0<=n<32
        static void primitiveLeftShift(int[] a, int len, int n) {
            if (len == 0 || n == 0)
                return;
            int n2 = 32 - n;
            for (int i=0, c=a[i], m=i+len-1; i<m; i++) {
                int b = c;
                c = a[i+1];
                a[i] = (b << n) | (c >>> n2);
            }
            a[len-1] <<= n;
        }
        /**
         * Calculate bitlength
  • 相关阅读:
    idea git使用记录
    会计科目中的借贷理解
    git使用合集
    Unsupported major.minor version 52.0
    sts问题合集
    idea导入工程
    (转)解决mybatis的mapper.xml查询不出数据,结果一直为null问题
    战争热诚的python全栈开发之路
    Python机器学习笔记:SVM(4)——sklearn实现
    Python机器学习笔记:SVM(3)——证明SVM
  • 原文地址:https://www.cnblogs.com/b-l-java/p/6033951.html
Copyright © 2011-2022 走看看