/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
 */
package java.math;

import static javaemul.internal.InternalPreconditions.checkCriticalArgument;
import static javaemul.internal.InternalPreconditions.checkNotNull;

import java.io.Serializable;
import java.util.Random;
import javaemul.internal.LongUtils;

/**
 * This class represents immutable integer numbers of arbitrary length. Large
 * numbers are typically used in security applications and therefore BigIntegers
 * offer dedicated functionality like the generation of large prime numbers or
 * the computation of modular inverse.
 * <p>
 * Since the class was modeled to offer all the functionality as the
 * {@link Integer} class does, it provides even methods that operate bitwise on
 * a two's complement representation of large integers. Note however that the
 * implementations favors an internal representation where magnitude and sign
 * are treated separately. Hence such operations are inefficient and should be
 * discouraged. In simple words: Do NOT implement any bit fields based on
 * BigInteger.
 */
public class BigInteger extends Number implements Comparable<BigInteger>,
    Serializable {

  /**
   * The {@code BigInteger} constant 1.
   */
  public static final BigInteger ONE = new BigInteger(1, 1);

  /* Fields used for the internal representation. */

  /**
   * The {@code BigInteger} constant 10.
   */
  public static final BigInteger TEN = new BigInteger(1, 10);

  /**
   * The {@code BigInteger} constant 0.
   */
  public static final BigInteger ZERO = new BigInteger(0, 0);

  /**
   * The {@code BigInteger} constant 0 used for comparison.
   */
  static final int EQUALS = 0;

  /**
   * The {@code BigInteger} constant 1 used for comparison.
   */
  static final int GREATER = 1;

  /**
   * The {@code BigInteger} constant -1 used for comparison.
   */
  static final int LESS = -1;

  /**
   * The {@code BigInteger} constant -1.
   */
  static final BigInteger MINUS_ONE = new BigInteger(-1, 1);

  /**
   * 2^32.
   */
  static final double POW32 = 4294967296d;

  /**
   * All the {@code BigInteger} numbers in the range [0,10] are cached.
   */
  static final BigInteger[] SMALL_VALUES = {
      ZERO, ONE, new BigInteger(1, 2), new BigInteger(1, 3),
      new BigInteger(1, 4), new BigInteger(1, 5), new BigInteger(1, 6),
      new BigInteger(1, 7), new BigInteger(1, 8), new BigInteger(1, 9), TEN};

  static final BigInteger[] TWO_POWS;

  /**
   * This is the serialVersionUID used by the sun implementation.
   */
  private static final long serialVersionUID = -8287574255936472291L;

  static {
    TWO_POWS = new BigInteger[32];
    for (int i = 0; i < TWO_POWS.length; i++) {
      TWO_POWS[i] = BigInteger.valueOf(1L << i);
    }
  }

  /**
   * Returns a random positive {@code BigInteger} instance in the range [0,
   * 2^(bitLength)-1] which is probably prime. The probability that the returned
   * {@code BigInteger} is prime is beyond (1-1/2^80).
   * <p>
   * <b>Implementation Note:</b> Currently {@code rnd} is ignored.
   *
   * @param bitLength length of the new {@code BigInteger} in bits.
   * @param rnd random generator used to generate the new {@code BigInteger}.
   * @return probably prime random {@code BigInteger} instance.
   * @throws ArithmeticException if {@code bitLength < 2}.
   */
  public static BigInteger probablePrime(int bitLength, Random rnd) {
    return new BigInteger(bitLength, 100, rnd);
  }

  public static BigInteger valueOf(long val) {
    if (val < 0) {
      if (val != -1) {
        return new BigInteger(-1, -val);
      }
      return MINUS_ONE;
    } else if (val <= 10) {
      return SMALL_VALUES[(int) val];
    } else {
      // (val > 10)
      return new BigInteger(1, val);
    }
  }

  static BigInteger getPowerOfTwo(int exp) {
    if (exp < TWO_POWS.length) {
      return TWO_POWS[exp];
    }
    int intCount = exp >> 5;
    int bitN = exp & 31;
    int resDigits[] = new int[intCount + 1];
    resDigits[intCount] = 1 << bitN;
    return new BigInteger(1, intCount + 1, resDigits);
  }

  public static BigInteger valueOf(double val) {
    if (val < 0) {
      if (val != -1) {
        return new BigInteger(-1, -val);
      }
      return MINUS_ONE;
    } else if (val <= 10) {
      return SMALL_VALUES[(int) val];
    } else {
      // (val > 10)
      return new BigInteger(1, val);
    }
  }

  /**
   * @see BigInteger#BigInteger(String, int)
   */
  private static void setFromString(BigInteger bi, String val, int radix) {
    int sign;
    int[] digits;
    int numberLength;
    int stringLength = val.length();
    int startChar;
    int endChar = stringLength;

    if (val.charAt(0) == '-') {
      sign = -1;
      startChar = 1;
      stringLength--;
    } else {
      sign = 1;
      startChar = 0;
    }
    /*
     * We use the following algorithm: split a string into portions of n
     * characters and convert each portion to an integer according to the radix.
     * Then convert an exp(radix, n) based number to binary using the
     * multiplication method. See D. Knuth, The Art of Computer Programming,
     * vol. 2.
     */

    int charsPerInt = Conversion.digitFitInInt[radix];
    int bigRadixDigitsLength = stringLength / charsPerInt;
    int topChars = stringLength % charsPerInt;

    if (topChars != 0) {
      bigRadixDigitsLength++;
    }
    digits = new int[bigRadixDigitsLength];
    // Get the maximal power of radix that fits in int
    int bigRadix = Conversion.bigRadices[radix - 2];
    // Parse an input string and accumulate the BigInteger's magnitude
    int digitIndex = 0; // index of digits array
    int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
    int newDigit;

    for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart
        + charsPerInt) {
      int bigRadixDigit = Integer.parseInt(
          val.substring(substrStart, substrEnd), radix);
      newDigit = Multiplication.multiplyByInt(digits, digitIndex, bigRadix);
      newDigit += Elementary.inplaceAdd(digits, digitIndex, bigRadixDigit);
      digits[digitIndex++] = newDigit;
    }
    numberLength = digitIndex;
    bi.sign = sign;
    bi.numberLength = numberLength;
    bi.digits = digits;
    bi.cutOffLeadingZeroes();
  }

  /**
   * Converts an integral double to an unsigned integer; ie 2^31 will be
   * returned as 0x80000000.
   *
   * @param val
   * @return val as an unsigned int
   */
  @SuppressWarnings("unusable-by-js")
  private static native int toUnsignedInt(double val) /*-{
    return val | 0;
  }-*/;

  /**
   * The magnitude of this big integer. This array is in little endian order and
   * each "digit" is a 32-bit unsigned integer. For example: {@code 13} is
   * represented as [ 13 ] {@code -13} is represented as [ 13 ] {@code 2^32 +
   * 13} is represented as [ 13, 1 ] {@code 2^64 + 13} is represented as [ 13,
   * 0, 1 ] {@code 2^31} is represented as [ Integer.MIN_VALUE ] The magnitude
   * array may be longer than strictly necessary, which results in additional
   * trailing zeros.
   *
   * <p>TODO(jat): consider changing to 24-bit integers for better performance
   * in browsers.
   */
  transient int digits[];

  /**
   * The length of this in measured in ints. Can be less than digits.length().
   */
  transient int numberLength;

  /**
   * The sign of this.
   */
  transient int sign;

  private transient int firstNonzeroDigit = -2;

  /**
   * Cache for the hash code.
   */
  private transient int hashCode = 0;

  /**
   * Constructs a new {@code BigInteger} from the given two's complement
   * representation. The most significant byte is the entry at index 0. The most
   * significant bit of this entry determines the sign of the new {@code
   * BigInteger} instance. The given array must not be empty.
   *
   * @param val two's complement representation of the new {@code BigInteger}.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if the length of {@code val} is zero.
   */
  public BigInteger(byte[] val) {
    if (val.length == 0) {
      // math.12=Zero length BigInteger
      throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$
    }
    if (val[0] < 0) {
      sign = -1;
      putBytesNegativeToIntegers(val);
    } else {
      sign = 1;
      putBytesPositiveToIntegers(val);
    }
    cutOffLeadingZeroes();
  }

  /**
   * Constructs a new {@code BigInteger} instance with the given sign and the
   * given magnitude. The sign is given as an integer (-1 for negative, 0 for
   * zero, 1 for positive). The magnitude is specified as a byte array. The most
   * significant byte is the entry at index 0.
   *
   * @param signum sign of the new {@code BigInteger} (-1 for negative, 0 for
   *          zero, 1 for positive).
   * @param magnitude magnitude of the new {@code BigInteger} with the most
   *          significant byte first.
   * @throws NullPointerException if {@code magnitude == null}.
   * @throws NumberFormatException if the sign is not one of -1, 0, 1 or if the
   *           sign is zero and the magnitude contains non-zero entries.
   */
  public BigInteger(int signum, byte[] magnitude) {
    checkNotNull(magnitude);

    if ((signum < -1) || (signum > 1)) {
      // math.13=Invalid signum value
      throw new NumberFormatException("Invalid signum value"); //$NON-NLS-1$
    }
    if (signum == 0) {
      for (byte element : magnitude) {
        if (element != 0) {
          // math.14=signum-magnitude mismatch
          throw new NumberFormatException("signum-magnitude mismatch"); //$NON-NLS-1$
        }
      }
    }
    if (magnitude.length == 0) {
      sign = 0;
      numberLength = 1;
      digits = new int[] {0};
    } else {
      sign = signum;
      putBytesPositiveToIntegers(magnitude);
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a random {@code BigInteger} instance in the range [0,
   * 2^(bitLength)-1] which is probably prime. The probability that the returned
   * {@code BigInteger} is prime is beyond (1-1/2^certainty).
   *
   * @param bitLength length of the new {@code BigInteger} in bits.
   * @param certainty tolerated primality uncertainty.
   * @param rnd is an optional random generator to be used.
   * @throws ArithmeticException if {@code bitLength} < 2.
   */
  public BigInteger(int bitLength, int certainty, Random rnd) {
    if (bitLength < 2) {
      // math.1C=bitLength < 2
      throw new ArithmeticException("bitLength < 2"); //$NON-NLS-1$
    }
    BigInteger me = Primality.consBigInteger(bitLength, certainty, rnd);
    sign = me.sign;
    numberLength = me.numberLength;
    digits = me.digits;
  }

  /**
   * Constructs a random non-negative {@code BigInteger} instance in the range
   * [0, 2^(numBits)-1].
   *
   * @param numBits maximum length of the new {@code BigInteger} in bits.
   * @param rnd is an optional random generator to be used.
   * @throws IllegalArgumentException if {@code numBits} < 0.
   */
  public BigInteger(int numBits, Random rnd) {
    checkCriticalArgument(numBits >= 0, "numBits must be non-negative");

    if (numBits == 0) {
      sign = 0;
      numberLength = 1;
      digits = new int[] {0};
    } else {
      sign = 1;
      numberLength = (numBits + 31) >> 5;
      digits = new int[numberLength];
      for (int i = 0; i < numberLength; i++) {
        digits[i] = rnd.nextInt();
      }
      // Using only the necessary bits
      digits[numberLength - 1] >>>= (-numBits) & 31;
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a new {@code BigInteger} instance from the string
   * representation. The string representation consists of an optional minus
   * sign followed by a non-empty sequence of decimal digits.
   *
   * @param val string representation of the new {@code BigInteger}.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if {@code val} is not a valid representation
   *           of a {@code BigInteger}.
   */
  public BigInteger(String val) {
    this(val, 10);
  }

  /**
   * Constructs a new {@code BigInteger} instance from the string
   * representation. The string representation consists of an optional minus
   * sign followed by a non-empty sequence of digits in the specified radix. For
   * the conversion the method {@code Character.digit(char, radix)} is used.
   *
   * @param val string representation of the new {@code BigInteger}.
   * @param radix the base to be used for the conversion.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if {@code val} is not a valid representation
   *           of a {@code BigInteger} or if {@code radix < Character.MIN_RADIX}
   *           or {@code radix > Character.MAX_RADIX}.
   */
  public BigInteger(String val, int radix) {
    checkNotNull(val);

    if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
      // math.11=Radix out of range
      throw new NumberFormatException("Radix out of range"); //$NON-NLS-1$
    }
    if (val.isEmpty()) {
      // math.12=Zero length BigInteger
      throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$
    }
    setFromString(this, val, radix);
  }

  /**
   * Constructs a number which array is of size 1.
   *
   * @param sign the sign of the number
   * @param value the only one digit of array
   */
  BigInteger(int sign, int value) {
    this.sign = sign;
    numberLength = 1;
    digits = new int[] {value};
  }

  /**
   * Creates a new {@code BigInteger} with the given sign and magnitude. This
   * constructor does not create a copy, so any changes to the reference will
   * affect the new number.
   *
   * @param signum The sign of the number represented by {@code digits}
   * @param digits The magnitude of the number
   */
  BigInteger(int signum, int digits[]) {
    if (digits.length == 0) {
      sign = 0;
      numberLength = 1;
      this.digits = new int[] {0};
    } else {
      sign = signum;
      numberLength = digits.length;
      this.digits = digits;
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a number without to create new space. This construct should be
   * used only if the three fields of representation are known.
   *
   * @param sign the sign of the number
   * @param numberLength the length of the internal array
   * @param digits a reference of some array created before
   */
  BigInteger(int sign, int numberLength, int[] digits) {
    this.sign = sign;
    this.numberLength = numberLength;
    this.digits = digits;
  }

  /**
   * Creates a new {@code BigInteger} whose value is equal to the specified
   * {@code long}.
   *
   * @param sign the sign of the number
   * @param val the value of the new {@code BigInteger}.
   */
  BigInteger(int sign, long val) {
    // PRE: (val >= 0) && (sign >= -1) && (sign <= 1)
    this.sign = sign;
    if (LongUtils.getHighBits(val) == 0) {
      // It fits in one 'int'
      numberLength = 1;
      digits = new int[] {(int) val};
    } else {
      numberLength = 2;
      digits = new int[] {(int) val, (int) (val >> 32)};
    }
  }

  /**
   * Creates a new {@code BigInteger} whose value is equal to the specified
   * {@code double} (which must be an integral value).
   *
   * @param sign the sign of the number
   * @param val the value of the new {@code BigInteger}.
   */
  private BigInteger(int sign, double val) {
    // PRE: (val >= 0) && (sign >= -1) && (sign <= 1)
    this.sign = sign;
    if (val < POW32) {
      // It fits in one 'int'
      numberLength = 1;
      digits = new int[] { toUnsignedInt(val) };
    } else {
      numberLength = 2;
      digits = new int[] { toUnsignedInt(val % POW32), toUnsignedInt(val / POW32) };
    }
  }

  /**
   * Returns a (new) {@code BigInteger} whose value is the absolute value of
   * {@code this}.
   *
   * @return {@code abs(this)}.
   */
  public BigInteger abs() {
    return ((sign < 0) ? new BigInteger(1, numberLength, digits) : this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this + val}.
   *
   * @param val value to be added to {@code this}.
   * @return {@code this + val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger add(BigInteger val) {
    return Elementary.add(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this & val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be and'ed with {@code this}.
   * @return {@code this & val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger and(BigInteger val) {
    return Logical.and(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this & ~val}.
   * Evaluating {@code x.andNot(val)} returns the same result as {@code
   * x.and(val.not())}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be not'ed and then and'ed with {@code this}.
   * @return {@code this & ~val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger andNot(BigInteger val) {
    return Logical.andNot(this, val);
  }

  /**
   * Use {@code bitLength(0)} if you want to know the length of the binary value
   * in bits.
   * <p>
   * Returns the number of bits in the binary representation of {@code this}
   * which differ from the sign bit. If {@code this} is positive the result is
   * equivalent to the number of bits set in the binary representation of
   * {@code this}. If {@code this} is negative the result is equivalent to the
   * number of bits set in the binary representation of {@code -this-1}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return number of bits in the binary representation of {@code this} which
   *         differ from the sign bit
   */
  public int bitCount() {
    return BitLevel.bitCount(this);
  }

  /**
   * Returns the length of the value's two's complement representation without
   * leading zeros for positive numbers / without leading ones for negative
   * values.
   * <p>
   * The two's complement representation of {@code this} will be at least
   * {@code bitLength() + 1} bits long.
   * <p>
   * The value will fit into an {@code int} if {@code bitLength() < 32} or into
   * a {@code long} if {@code bitLength() < 64}.
   *
   * @return the length of the minimal two's complement representation for
   *         {@code this} without the sign bit.
   */
  public int bitLength() {
    return BitLevel.bitLength(this);
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code byte} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code byte}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code byte}.
   */
  public byte byteValueExact() {
    if (numberLength <= 1 && bitLength() < Byte.SIZE) {
      return byteValue();
    }
    throw new ArithmeticException("out of byte range");
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n cleared. The result is
   * equivalent to {@code this & ~(2^n)}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be cleared.
   * @return {@code this & ~(2^n)}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger clearBit(int n) {
    if (testBit(n)) {
      return BitLevel.flipBit(this, n);
    }
    return this;
  }

  /**
   * Compares this {@code BigInteger} with {@code val}. Returns one of the three
   * values 1, 0, or -1.
   *
   * @param val value to be compared with {@code this}.
   * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val} ,
   *         {@code 0} if {@code this == val}.
   * @throws NullPointerException if {@code val == null}.
   */
  @Override
  public int compareTo(BigInteger val) {
    if (sign > val.sign) {
      return GREATER;
    }
    if (sign < val.sign) {
      return LESS;
    }
    if (numberLength > val.numberLength) {
      return sign;
    }
    if (numberLength < val.numberLength) {
      return -val.sign;
    }
    // Equal sign and equal numberLength
    return (sign * Elementary.compareArrays(digits, val.digits, numberLength));
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this / divisor}.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code this / divisor}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   */
  public BigInteger divide(BigInteger divisor) {
    if (divisor.sign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int divisorSign = divisor.sign;
    if (divisor.isOne()) {
      return ((divisor.sign > 0) ? this : this.negate());
    }
    int thisSign = sign;
    int thisLen = numberLength;
    int divisorLen = divisor.numberLength;
    if (thisLen + divisorLen == 2) {
      long val = (digits[0] & 0xFFFFFFFFL) / (divisor.digits[0] & 0xFFFFFFFFL);
      if (thisSign != divisorSign) {
        val = -val;
      }
      return valueOf(val);
    }
    int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(digits, divisor.digits, thisLen));
    if (cmp == EQUALS) {
      return ((thisSign == divisorSign) ? ONE : MINUS_ONE);
    }
    if (cmp == LESS) {
      return ZERO;
    }
    int resLength = thisLen - divisorLen + 1;
    int resDigits[] = new int[resLength];
    int resSign = ((thisSign == divisorSign) ? 1 : -1);
    if (divisorLen == 1) {
      Division.divideArrayByInt(resDigits, digits, thisLen, divisor.digits[0]);
    } else {
      Division.divide(resDigits, resLength, digits, thisLen, divisor.digits,
          divisorLen);
    }
    BigInteger result = new BigInteger(resSign, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Returns a {@code BigInteger} array which contains {@code this / divisor} at
   * index 0 and {@code this % divisor} at index 1.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code [this / divisor, this % divisor]}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   * @see #divide
   * @see #remainder
   */
  public BigInteger[] divideAndRemainder(BigInteger divisor) {
    int divisorSign = divisor.sign;
    if (divisorSign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int divisorLen = divisor.numberLength;
    int[] divisorDigits = divisor.digits;
    if (divisorLen == 1) {
      return Division.divideAndRemainderByInteger(this, divisorDigits[0],
          divisorSign);
    }
    // res[0] is a quotient and res[1] is a remainder:
    int[] thisDigits = digits;
    int thisLen = numberLength;
    int cmp = (thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(thisDigits, divisorDigits, thisLen);
    if (cmp < 0) {
      return new BigInteger[] {ZERO, this};
    }
    int thisSign = sign;
    int quotientLength = thisLen - divisorLen + 1;
    int remainderLength = divisorLen;
    int quotientSign = ((thisSign == divisorSign) ? 1 : -1);
    int quotientDigits[] = new int[quotientLength];
    int remainderDigits[] = Division.divide(quotientDigits, quotientLength,
        thisDigits, thisLen, divisorDigits, divisorLen);
    BigInteger result0 = new BigInteger(quotientSign, quotientLength,
        quotientDigits);
    BigInteger result1 = new BigInteger(thisSign, remainderLength,
        remainderDigits);
    result0.cutOffLeadingZeroes();
    result1.cutOffLeadingZeroes();
    return new BigInteger[] {result0, result1};
  }

  /**
   * Returns this {@code BigInteger} as an double value. If {@code this} is too
   * big to be represented as an double, then {@code Double.POSITIVE_INFINITY}
   * or {@code Double.NEGATIVE_INFINITY} is returned. Note, that not all
   * integers x in the range [-Double.MAX_VALUE, Double.MAX_VALUE] can be
   * represented as a double. The double representation has a mantissa of length
   * 53. For example, 2^53+1 = 9007199254740993 is returned as double
   * 9007199254740992.0.
   *
   * @return this {@code BigInteger} as a double value
   */
  @Override
  public double doubleValue() {
    return Double.parseDouble(this.toString());
  }

  /**
   * Returns {@code true} if {@code x} is a BigInteger instance and if this
   * instance is equal to this {@code BigInteger}.
   *
   * @param x object to be compared with {@code this}.
   * @return true if {@code x} is a BigInteger and {@code this == x}, {@code
   *         false} otherwise.
   */
  @Override
  public boolean equals(Object x) {
    if (this == x) {
      return true;
    }
    if (x instanceof BigInteger) {
      BigInteger x1 = (BigInteger) x;
      return sign == x1.sign && numberLength == x1.numberLength
          && equalsArrays(x1.digits);
    }
    return false;
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n flipped. The result is
   * equivalent to {@code this ^ 2^n}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be flipped.
   * @return {@code this ^ 2^n}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger flipBit(int n) {
    if (n < 0) {
      // math.15=Negative bit address
      throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$
    }
    return BitLevel.flipBit(this, n);
  }

  /**
   * Returns this {@code BigInteger} as an float value. If {@code this} is too
   * big to be represented as an float, then {@code Float.POSITIVE_INFINITY} or
   * {@code Float.NEGATIVE_INFINITY} is returned. Note, that not all integers x
   * in the range [-Float.MAX_VALUE, Float.MAX_VALUE] can be represented as a
   * float. The float representation has a mantissa of length 24. For example,
   * 2^24+1 = 16777217 is returned as float 16777216.0.
   *
   * @return this {@code BigInteger} as a float value.
   */
  @Override
  public float floatValue() {
    return Float.parseFloat(this.toString());
  }

  /**
   * Returns a new {@code BigInteger} whose value is greatest common divisor of
   * {@code this} and {@code val}. If {@code this==0} and {@code val==0} then
   * zero is returned, otherwise the result is positive.
   *
   * @param val value with which the greatest common divisor is computed.
   * @return {@code gcd(this, val)}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger gcd(BigInteger val) {
    BigInteger val1 = this.abs();
    BigInteger val2 = val.abs();
    // To avoid a possible division by zero
    if (val1.signum() == 0) {
      return val2;
    } else if (val2.signum() == 0) {
      return val1;
    }

    // Optimization for small operands
    // (op2.bitLength() < 64) and (op1.bitLength() < 64)
    if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0)))
        && (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0))) {
      return BigInteger.valueOf(Division.gcdBinary(val1.longValue(),
          val2.longValue()));
    }

    return Division.gcdBinary(val1.copy(), val2.copy());
  }

  /**
   * Returns the position of the lowest set bit in the two's complement
   * representation of this {@code BigInteger}. If all bits are zero (this=0)
   * then -1 is returned as result.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return position of lowest bit if {@code this != 0}, {@code -1} otherwise
   */
  public int getLowestSetBit() {
    if (sign == 0) {
      return -1;
    }
    // (sign != 0) implies that exists some non zero digit
    int i = getFirstNonzeroDigit();
    return ((i << 5) + Integer.numberOfTrailingZeros(digits[i]));
  }

  /**
   * Returns a hash code for this {@code BigInteger}.
   *
   * @return hash code for {@code this}.
   */
  @Override
  public int hashCode() {
    if (hashCode != 0) {
      return hashCode;
    }
    for (int i = 0; i < digits.length; i++) {
      hashCode = (hashCode * 33 + (digits[i] & 0xffffffff));
    }
    hashCode = hashCode * sign;
    return hashCode;
  }

  /**
   * Returns this {@code BigInteger} as an int value. If {@code this} is too big
   * to be represented as an int, then {@code this} % 2^32 is returned.
   *
   * @return this {@code BigInteger} as an int value.
   */
  @Override
  public int intValue() {
    int i = digits[0];
    // i is always positive except for Integer.MIN_VALUE because of int overflow
    return (sign > 0 || i == Integer.MIN_VALUE) ? i : -i;
  }

  /**
   * Converts value of this {@code BigInteger} to an {@code int} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to an {@code int}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in an {@code int}.
   */
  public int intValueExact() {
    if (numberLength <= 1 && bitLength() < Integer.SIZE) {
      return intValue();
    }
    throw new ArithmeticException("out of int range");
  }

  /**
   * Tests whether this {@code BigInteger} is probably prime. If {@code true} is
   * returned, then this is prime with a probability beyond (1-1/2^certainty).
   * If {@code false} is returned, then this is definitely composite. If the
   * argument {@code certainty} <= 0, then this method returns true.
   *
   * @param certainty tolerated primality uncertainty.
   * @return {@code true}, if {@code this} is probably prime, {@code false}
   *         otherwise.
   */
  public boolean isProbablePrime(int certainty) {
    return Primality.isProbablePrime(abs(), certainty);
  }

  /**
   * Returns this {@code BigInteger} as an long value. If {@code this} is too
   * big to be represented as an long, then {@code this} % 2^64 is returned.
   *
   * @return this {@code BigInteger} as a long value.
   */
  @Override
  public long longValue() {
    long value =
        numberLength > 1
            ? LongUtils.fromBits(digits[0], digits[1])
            : LongUtils.fromBits(digits[0], 0);
    return sign > 0 ? value : -value;
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code long} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code long}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code long}.
   */
  public long longValueExact() {
    if (numberLength <= 2 && bitLength() < Long.SIZE) {
      return longValue();
    }
    throw new ArithmeticException("out of long range");
  }

  /**
   * Returns the maximum of this {@code BigInteger} and {@code val}.
   *
   * @param val value to be used to compute the maximum with {@code this}
   * @return {@code max(this, val)}
   * @throws NullPointerException if {@code val == null}
   */
  public BigInteger max(BigInteger val) {
    return ((this.compareTo(val) == GREATER) ? this : val);
  }

  /**
   * Returns the minimum of this {@code BigInteger} and {@code val}.
   *
   * @param val value to be used to compute the minimum with {@code this}.
   * @return {@code min(this, val)}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger min(BigInteger val) {
    return ((this.compareTo(val) == LESS) ? this : val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this mod m}. The
   * modulus {@code m} must be positive. The result is guaranteed to be in the
   * interval {@code [0, m)} (0 inclusive, m exclusive). The behavior of this
   * function is not equivalent to the behavior of the % operator defined for
   * the built-in {@code int}'s.
   *
   * @param m the modulus.
   * @return {@code this mod m}.
   * @throws NullPointerException if {@code m == null}.
   * @throws ArithmeticException if {@code m < 0}.
   */
  public BigInteger mod(BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    BigInteger rem = remainder(m);
    return ((rem.sign < 0) ? rem.add(m) : rem);
  }

  // @Override
  // public double doubleValue() {
  // return Conversion.bigInteger2Double(this);
  // }

  /**
   * Returns a new {@code BigInteger} whose value is {@code 1/this mod m}. The
   * modulus {@code m} must be positive. The result is guaranteed to be in the
   * interval {@code [0, m)} (0 inclusive, m exclusive). If {@code this} is not
   * relatively prime to m, then an exception is thrown.
   *
   * @param m the modulus.
   * @return {@code 1/this mod m}.
   * @throws NullPointerException if {@code m == null}
   * @throws ArithmeticException if {@code m < 0 or} if {@code this} is not
   *           relatively prime to {@code m}
   */
  public BigInteger modInverse(BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    // If both are even, no inverse exists
    if (!(testBit(0) || m.testBit(0))) {
      // math.19=BigInteger not invertible.
      throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$
    }
    if (m.isOne()) {
      return ZERO;
    }

    // From now on: (m > 1)
    BigInteger res = Division.modInverseMontgomery(abs().mod(m), m);
    if (res.sign == 0) {
      // math.19=BigInteger not invertible.
      throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$
    }

    res = ((sign < 0) ? m.subtract(res) : res);
    return res;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this^exponent mod m}
   * . The modulus {@code m} must be positive. The result is guaranteed to be in
   * the interval {@code [0, m)} (0 inclusive, m exclusive). If the exponent is
   * negative, then {@code this.modInverse(m)^(-exponent) mod m)} is computed.
   * The inverse of this only exists if {@code this} is relatively prime to m,
   * otherwise an exception is thrown.
   *
   * @param exponent the exponent.
   * @param m the modulus.
   * @return {@code this^exponent mod val}.
   * @throws NullPointerException if {@code m == null} or {@code exponent ==
   *           null}.
   * @throws ArithmeticException if {@code m < 0} or if {@code exponent<0} and
   *           this is not relatively prime to {@code m}.
   */
  public BigInteger modPow(BigInteger exponent, BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    BigInteger base = this;

    if (m.isOne() | (exponent.sign > 0 & base.sign == 0)) {
      return BigInteger.ZERO;
    }
    if (base.sign == 0 && exponent.sign == 0) {
      return BigInteger.ONE;
    }
    if (exponent.sign < 0) {
      base = modInverse(m);
      exponent = exponent.negate();
    }
    // From now on: (m > 0) and (exponent >= 0)
    BigInteger res = (m.testBit(0)) ? Division.oddModPow(base.abs(), exponent,
        m) : Division.evenModPow(base.abs(), exponent, m);
    if ((base.sign < 0) && exponent.testBit(0)) {
      // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
      res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
    }
    // else exponent is even, so base^exp is positive
    return res;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this * val}.
   *
   * @param val value to be multiplied with {@code this}.
   * @return {@code this * val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger multiply(BigInteger val) {
    // This let us to throw NullPointerException when val == null
    if (val.sign == 0) {
      return ZERO;
    }
    if (sign == 0) {
      return ZERO;
    }
    return Multiplication.multiply(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is the {@code -this}.
   *
   * @return {@code -this}.
   */
  public BigInteger negate() {
    return ((sign == 0) ? this : new BigInteger(-sign, numberLength, digits));
  }

  /**
   * Returns the smallest integer x > {@code this} which is probably prime as a
   * {@code BigInteger} instance. The probability that the returned {@code
   * BigInteger} is prime is beyond (1-1/2^80).
   *
   * @return smallest integer > {@code this} which is robably prime.
   * @throws ArithmeticException if {@code this < 0}.
   */
  public BigInteger nextProbablePrime() {
    if (sign < 0) {
      // math.1A=start < 0: {0}
      throw new ArithmeticException("start < 0: " + this); //$NON-NLS-1$
    }
    return Primality.nextProbablePrime(this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code ~this}. The result
   * of this operation is {@code -this-1}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return {@code ~this}.
   */
  public BigInteger not() {
    return Logical.not(this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this | val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be or'ed with {@code this}.
   * @return {@code this | val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger or(BigInteger val) {
    return Logical.or(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this ^ exp}.
   *
   * @param exp exponent to which {@code this} is raised.
   * @return {@code this ^ exp}.
   * @throws ArithmeticException if {@code exp < 0}.
   */
  public BigInteger pow(int exp) {
    if (exp < 0) {
      // math.16=Negative exponent
      throw new ArithmeticException("Negative exponent"); //$NON-NLS-1$
    }
    if (exp == 0) {
      return ONE;
    } else if (exp == 1 || equals(ONE) || equals(ZERO)) {
      return this;
    }

    // if even take out 2^x factor which we can
    // calculate by shifting.
    if (!testBit(0)) {
      int x = 1;
      while (!testBit(x)) {
        x++;
      }
      return getPowerOfTwo(x * exp).multiply(this.shiftRight(x).pow(exp));
    }
    return Multiplication.pow(this, exp);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this % divisor}.
   * Regarding signs this methods has the same behavior as the % operator on
   * int's, i.e. the sign of the remainder is the same as the sign of this.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code this % divisor}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   */
  public BigInteger remainder(BigInteger divisor) {
    if (divisor.sign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int thisLen = numberLength;
    int divisorLen = divisor.numberLength;
    if (((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(digits, divisor.digits, thisLen)) == LESS) {
      return this;
    }
    int resLength = divisorLen;
    int resDigits[] = new int[resLength];
    if (resLength == 1) {
      resDigits[0] = Division.remainderArrayByInt(digits, thisLen,
          divisor.digits[0]);
    } else {
      int qLen = thisLen - divisorLen + 1;
      resDigits = Division.divide(null, qLen, digits, thisLen, divisor.digits,
          divisorLen);
    }
    BigInteger result = new BigInteger(sign, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n set. The result is
   * equivalent to {@code this | 2^n}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be set.
   * @return {@code this | 2^n}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger setBit(int n) {
    if (!testBit(n)) {
      return BitLevel.flipBit(this, n);
    }
    return this;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this << n}. The
   * result is equivalent to {@code this * 2^n} if n >= 0. The shift distance
   * may be negative which means that {@code this} is shifted right. The result
   * then corresponds to {@code floor(this / 2^(-n))}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method on negative values is not
   * recommended as the current implementation is not efficient.
   *
   * @param n shift distance.
   * @return {@code this << n} if {@code n >= 0}; {@code this >> (-n)}.
   *         otherwise
   */
  public BigInteger shiftLeft(int n) {
    if ((n == 0) || (sign == 0)) {
      return this;
    }
    return ((n > 0) ? BitLevel.shiftLeft(this, n) : BitLevel.shiftRight(this,
        -n));
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this >> n}. For
   * negative arguments, the result is also negative. The shift distance may be
   * negative which means that {@code this} is shifted left.
   * <p>
   * <b>Implementation Note:</b> Usage of this method on negative values is not
   * recommended as the current implementation is not efficient.
   *
   * @param n shift distance
   * @return {@code this >> n} if {@code n >= 0}; {@code this << (-n)} otherwise
   */
  public BigInteger shiftRight(int n) {
    if ((n == 0) || (sign == 0)) {
      return this;
    }
    return ((n > 0) ? BitLevel.shiftRight(this, n) : BitLevel.shiftLeft(this,
        -n));
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code short} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code short}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code short}.
   */
  public short shortValueExact() {
    if (numberLength <= 1 && bitLength() < Short.SIZE) {
      return shortValue();
    }
    throw new ArithmeticException("out of short range");
  }

  /**
   * Returns the sign of this {@code BigInteger}.
   *
   * @return {@code -1} if {@code this < 0}, {@code 0} if {@code this == 0},
   *         {@code 1} if {@code this > 0}.
   */
  public int signum() {
    return sign;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this - val}.
   *
   * @param val value to be subtracted from {@code this}.
   * @return {@code this - val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger subtract(BigInteger val) {
    return Elementary.subtract(this, val);
  }

  /**
   * Tests whether the bit at position n in {@code this} is set. The result is
   * equivalent to {@code this & (2^n) != 0}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be inspected.
   * @return {@code this & (2^n) != 0}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public boolean testBit(int n) {
    if (n == 0) {
      return ((digits[0] & 1) != 0);
    }
    if (n < 0) {
      // math.15=Negative bit address
      throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$
    }
    int intCount = n >> 5;
    if (intCount >= numberLength) {
      return (sign < 0);
    }
    int digit = digits[intCount];
    n = (1 << (n & 31)); // int with 1 set to the needed position
    if (sign < 0) {
      int firstNonZeroDigit = getFirstNonzeroDigit();
      if (intCount < firstNonZeroDigit) {
        return false;
      } else if (firstNonZeroDigit == intCount) {
        digit = -digit;
      } else {
        digit = ~digit;
      }
    }
    return ((digit & n) != 0);
  }

  /**
   * Returns the two's complement representation of this BigInteger in a byte
   * array.
   *
   * @return two's complement representation of {@code this}.
   */
  public byte[] toByteArray() {
    if (this.sign == 0) {
      return new byte[] {0};
    }
    BigInteger temp = this;
    int bitLen = bitLength();
    int iThis = getFirstNonzeroDigit();
    int bytesLen = (bitLen >> 3) + 1;
    /*
     * Puts the little-endian int array representing the magnitude of this
     * BigInteger into the big-endian byte array.
     */
    byte[] bytes = new byte[bytesLen];
    int firstByteNumber = 0;
    int highBytes;
    int digitIndex = 0;
    int bytesInInteger = 4;
    int digit;
    int hB;

    if (bytesLen - (numberLength << 2) == 1) {
      bytes[0] = (byte) ((sign < 0) ? -1 : 0);
      highBytes = 4;
      firstByteNumber++;
    } else {
      hB = bytesLen & 3;
      highBytes = (hB == 0) ? 4 : hB;
    }

    digitIndex = iThis;
    bytesLen -= iThis << 2;

    if (sign < 0) {
      digit = -temp.digits[digitIndex];
      digitIndex++;
      if (digitIndex == numberLength) {
        bytesInInteger = highBytes;
      }
      for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
        bytes[--bytesLen] = (byte) digit;
      }
      while (bytesLen > firstByteNumber) {
        digit = ~temp.digits[digitIndex];
        digitIndex++;
        if (digitIndex == numberLength) {
          bytesInInteger = highBytes;
        }
        for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
          bytes[--bytesLen] = (byte) digit;
        }
      }
    } else {
      while (bytesLen > firstByteNumber) {
        digit = temp.digits[digitIndex];
        digitIndex++;
        if (digitIndex == numberLength) {
          bytesInInteger = highBytes;
        }
        for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
          bytes[--bytesLen] = (byte) digit;
        }
      }
    }
    return bytes;
  }

  /**
   * Returns a string representation of this {@code BigInteger} in decimal form.
   *
   * @return a string representation of {@code this} in decimal form.
   */
  @Override
  public String toString() {
    return Conversion.toDecimalScaledString(this, 0);
  }

  /**
   * Returns a string containing a string representation of this {@code
   * BigInteger} with base radix. If {@code radix} is less than
   * {@link Character#MIN_RADIX} or greater than {@link Character#MAX_RADIX}
   * then a decimal representation is returned. The characters of the string
   * representation are generated with method {@link Character#forDigit}.
   *
   * @param radix base to be used for the string representation.
   * @return a string representation of this with radix 10.
   */
  public String toString(int radix) {
    return Conversion.bigInteger2String(this, radix);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this ^ val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be xor'ed with {@code this}
   * @return {@code this ^ val}
   * @throws NullPointerException if {@code val == null}
   */
  public BigInteger xor(BigInteger val) {
    return Logical.xor(this, val);
  }

  /*
   * Returns a copy of the current instance to achieve immutability
   */
  BigInteger copy() {
    int[] copyDigits = new int[numberLength];
    System.arraycopy(digits, 0, copyDigits, 0, numberLength);
    return new BigInteger(sign, numberLength, copyDigits);
  }

  /* Private Methods */

  /**
   * Decreases {@code numberLength} if there are zero high elements.
   */
  final void cutOffLeadingZeroes() {
    while ((numberLength > 0) && (digits[--numberLength] == 0)) {
      // Empty
    }
    if (digits[numberLength++] == 0) {
      sign = 0;
    }
  }

  boolean equalsArrays(final int[] b) {
    int i;
    for (i = numberLength - 1; (i >= 0) && (digits[i] == b[i]); i--) {
      // Empty
    }
    return i < 0;
  }

  int getFirstNonzeroDigit() {
    if (firstNonzeroDigit == -2) {
      int i;
      if (this.sign == 0) {
        i = -1;
      } else {
        for (i = 0; digits[i] == 0; i++) {
          // Empty
        }
      }
      firstNonzeroDigit = i;
    }
    return firstNonzeroDigit;
  }

  /**
   * Tests if {@code this.abs()} is equals to {@code ONE}.
   */
  boolean isOne() {
    return ((numberLength == 1) && (digits[0] == 1));
  }

  BigInteger shiftLeftOneBit() {
    return (sign == 0) ? this : BitLevel.shiftLeftOneBit(this);
  }

  void unCache() {
    firstNonzeroDigit = -2;
  }

  /**
   * Puts a big-endian byte array into a little-endian applying two complement.
   */
  private void putBytesNegativeToIntegers(byte[] byteValues) {
    int bytesLen = byteValues.length;
    int highBytes = bytesLen & 3;
    numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1);
    digits = new int[numberLength];
    int i = 0;
    // Setting the sign
    digits[numberLength - 1] = -1;
    // Put bytes to the int array starting from the end of the byte array
    while (bytesLen > highBytes) {
      digits[i] = (byteValues[--bytesLen] & 0xFF)
          | (byteValues[--bytesLen] & 0xFF) << 8
          | (byteValues[--bytesLen] & 0xFF) << 16
          | (byteValues[--bytesLen] & 0xFF) << 24;
      if (digits[i] != 0) {
        digits[i] = -digits[i];
        firstNonzeroDigit = i;
        i++;
        while (bytesLen > highBytes) {
          digits[i] = (byteValues[--bytesLen] & 0xFF)
              | (byteValues[--bytesLen] & 0xFF) << 8
              | (byteValues[--bytesLen] & 0xFF) << 16
              | (byteValues[--bytesLen] & 0xFF) << 24;
          digits[i] = ~digits[i];
          i++;
        }
        break;
      }
      i++;
    }
    if (highBytes != 0) {
      // Put the first bytes in the highest element of the int array
      if (firstNonzeroDigit != -2) {
        for (int j = 0; j < bytesLen; j++) {
          digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
        }
        digits[i] = ~digits[i];
      } else {
        for (int j = 0; j < bytesLen; j++) {
          digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
        }
        digits[i] = -digits[i];
      }
    }
  }

  /**
   * Puts a big-endian byte array into a little-endian int array.
   */
  private void putBytesPositiveToIntegers(byte[] byteValues) {
    int bytesLen = byteValues.length;
    int highBytes = bytesLen & 3;
    numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1);
    digits = new int[numberLength];
    int i = 0;
    // Put bytes to the int array starting from the end of the byte array
    while (bytesLen > highBytes) {
      digits[i++] = (byteValues[--bytesLen] & 0xFF)
          | (byteValues[--bytesLen] & 0xFF) << 8
          | (byteValues[--bytesLen] & 0xFF) << 16
          | (byteValues[--bytesLen] & 0xFF) << 24;
    }
    // Put the first bytes in the highest element of the int array
    for (int j = 0; j < bytesLen; j++) {
      digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
    }
  }
}
