/*
 * 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;

/**
 * The library implements some logical operations over {@code BigInteger}. The
 * operations provided are listed below. <ul type="circle"> <li>not</li> <li>and
 * </li> <li>andNot</li> <li>or</li> <li>xor</li> </ul>
 */
class Logical {

  /**
   * @see BigInteger#and(BigInteger)
   * @param val
   * @param that
   * @return
   */
  static BigInteger and(BigInteger val, BigInteger that) {
    if (that.sign == 0 || val.sign == 0) {
      return BigInteger.ZERO;
    }
    if (that.equals(BigInteger.MINUS_ONE)) {
      return val;
    }
    if (val.equals(BigInteger.MINUS_ONE)) {
      return that;
    }

    if (val.sign > 0) {
      if (that.sign > 0) {
        return andPositive(val, that);
      } else {
        return andDiffSigns(val, that);
      }
    } else {
      if (that.sign > 0) {
        return andDiffSigns(that, val);
      } else if (val.numberLength > that.numberLength) {
        return andNegative(val, that);
      } else {
        return andNegative(that, val);
      }
    }
  }

  /**
   * Return sign = positive.magnitude & magnitude = -negative.magnitude.
   * @param positive
   * @param negative
   * @return
   */
  static BigInteger andDiffSigns(BigInteger positive, BigInteger negative) {
    // PRE: positive is positive and negative is negative
    int iPos = positive.getFirstNonzeroDigit();
    int iNeg = negative.getFirstNonzeroDigit();

    // Look if the trailing zeros of the negative will "blank" all
    // the positive digits
    if (iNeg >= positive.numberLength) {
      return BigInteger.ZERO;
    }
    int resLength = positive.numberLength;
    int resDigits[] = new int[resLength];

    // Must start from max(iPos, iNeg)
    int i = Math.max(iPos, iNeg);
    if (i == iNeg) {
      resDigits[i] = -negative.digits[i] & positive.digits[i];
      i++;
    }
    int limit = Math.min(negative.numberLength, positive.numberLength);
    for (; i < limit; i++) {
      resDigits[i] = ~negative.digits[i] & positive.digits[i];
    }
    // if the negative was shorter must copy the remaining digits
    // from positive
    if (i >= negative.numberLength) {
      for (; i < positive.numberLength; i++) {
        resDigits[i] = positive.digits[i];
      }
    } // else positive ended and must "copy" virtual 0's, do nothing then

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = -1, magnitude = -(-longer.magnitude & -shorter.magnitude).
   * @param longer
   * @param shorter
   * @return
   */
  static BigInteger andNegative(BigInteger longer, BigInteger shorter) {
    // PRE: longer and shorter are negative
    // PRE: longer has at least as many digits as shorter
    int iLonger = longer.getFirstNonzeroDigit();
    int iShorter = shorter.getFirstNonzeroDigit();

    // Does shorter matter?
    if (iLonger >= shorter.numberLength) {
      return longer;
    }

    int resLength;
    int resDigits[];
    int i = Math.max(iShorter, iLonger);
    int digit;
    if (iShorter > iLonger) {
      digit = -shorter.digits[i] & ~longer.digits[i];
    } else if (iShorter < iLonger) {
      digit = ~shorter.digits[i] & -longer.digits[i];
    } else {
      digit = -shorter.digits[i] & -longer.digits[i];
    }
    if (digit == 0) {
      for (i++; i < shorter.numberLength
          && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++) {
        // digit
      }
      // = ~longer.digits[i] & ~shorter.digits[i]
      if (digit == 0) {
        // shorter has only the remaining virtual sign bits
        for (; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++) {
          // empty
        }
        if (digit == 0) {
          resLength = longer.numberLength + 1;
          resDigits = new int[resLength];
          resDigits[resLength - 1] = 1;

          BigInteger result = new BigInteger(-1, resLength, resDigits);
          return result;
        }
      }
    }
    resLength = longer.numberLength;
    resDigits = new int[resLength];
    resDigits[i] = -digit;
    for (i++; i < shorter.numberLength; i++) {
      // resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];)
      resDigits[i] = longer.digits[i] | shorter.digits[i];
    }
    // shorter has only the remaining virtual sign bits
    for (; i < longer.numberLength; i++) {
      resDigits[i] = longer.digits[i];
    }

    BigInteger result = new BigInteger(-1, resLength, resDigits);
    return result;
  }

  /**
   * @see BigInteger#andNot(BigInteger)
   * @param val
   * @param that
   * @return
   */
  static BigInteger andNot(BigInteger val, BigInteger that) {
    if (that.sign == 0) {
      return val;
    }
    if (val.sign == 0) {
      return BigInteger.ZERO;
    }
    if (val.equals(BigInteger.MINUS_ONE)) {
      return that.not();
    }
    if (that.equals(BigInteger.MINUS_ONE)) {
      return BigInteger.ZERO;
    }

    // if val == that, return 0

    if (val.sign > 0) {
      if (that.sign > 0) {
        return andNotPositive(val, that);
      } else {
        return andNotPositiveNegative(val, that);
      }
    } else {
      if (that.sign > 0) {
        return andNotNegativePositive(val, that);
      } else {
        return andNotNegative(val, that);
      }
    }
  }

  /**
   * Return sign = 1, magnitude = -val.magnitude & ~(-that.magnitude).
   * @param val
   * @param that
   * @return
   */
  static BigInteger andNotNegative(BigInteger val, BigInteger that) {
    // PRE: val < 0 && that < 0
    int iVal = val.getFirstNonzeroDigit();
    int iThat = that.getFirstNonzeroDigit();

    if (iVal >= that.numberLength) {
      return BigInteger.ZERO;
    }

    int resLength = that.numberLength;
    int resDigits[] = new int[resLength];
    int limit;
    int i = iVal;
    if (iVal < iThat) {
      // resDigits[i] = -val.digits[i] & -1;
      resDigits[i] = -val.digits[i];
      limit = Math.min(val.numberLength, iThat);
      for (i++; i < limit; i++) {
        // resDigits[i] = ~val.digits[i] & -1;
        resDigits[i] = ~val.digits[i];
      }
      if (i == val.numberLength) {
        for (; i < iThat; i++) {
          // resDigits[i] = -1 & -1;
          resDigits[i] = -1;
        }
        // resDigits[i] = -1 & ~-that.digits[i];
        resDigits[i] = that.digits[i] - 1;
      } else {
        // resDigits[i] = ~val.digits[i] & ~-that.digits[i];
        resDigits[i] = ~val.digits[i] & (that.digits[i] - 1);
      }
    } else if (iThat < iVal) {
      // resDigits[i] = -val.digits[i] & ~~that.digits[i];
      resDigits[i] = -val.digits[i] & that.digits[i];
    } else {
      // resDigits[i] = -val.digits[i] & ~-that.digits[i];
      resDigits[i] = -val.digits[i] & (that.digits[i] - 1);
    }

    limit = Math.min(val.numberLength, that.numberLength);
    for (i++; i < limit; i++) {
      // resDigits[i] = ~val.digits[i] & ~~that.digits[i];
      resDigits[i] = ~val.digits[i] & that.digits[i];
    }
    for (; i < that.numberLength; i++) {
      // resDigits[i] = -1 & ~~that.digits[i];
      resDigits[i] = that.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = -1, magnitude = -(-negative.magnitude & ~positive.magnitude).
   * @param negative
   * @param positive
   * @return
   */
  static BigInteger andNotNegativePositive(BigInteger negative,
      BigInteger positive) {
    // PRE: negative < 0 && positive > 0
    int resLength;
    int resDigits[];
    int limit;
    int digit;

    int iNeg = negative.getFirstNonzeroDigit();
    int iPos = positive.getFirstNonzeroDigit();

    if (iNeg >= positive.numberLength) {
      return negative;
    }

    resLength = Math.max(negative.numberLength, positive.numberLength);
    int i = iNeg;
    if (iPos > iNeg) {
      resDigits = new int[resLength];
      limit = Math.min(negative.numberLength, iPos);
      for (; i < limit; i++) {
        // 1st case: resDigits [i] = -(-negative.digits[i] & (~0))
        // otherwise: resDigits[i] = ~(~negative.digits[i] & ~0) ;
        resDigits[i] = negative.digits[i];
      }
      if (i == negative.numberLength) {
        for (i = iPos; i < positive.numberLength; i++) {
          // resDigits[i] = ~(~positive.digits[i] & -1);
          resDigits[i] = positive.digits[i];
        }
      }
    } else {
      digit = -negative.digits[i] & ~positive.digits[i];
      if (digit == 0) {
        limit = Math.min(positive.numberLength, negative.numberLength);
        for (i++; i < limit
            && (digit = ~(negative.digits[i] | positive.digits[i])) == 0; i++) {
          // digit
        }
        // = ~negative.digits[i] & ~positive.digits[i]
        if (digit == 0) {
          // the shorter has only the remaining virtual sign bits
          for (; i < positive.numberLength
              && (digit = ~positive.digits[i]) == 0; i++) {
            // digit = -1 & ~positive.digits[i]
          }
          for (; i < negative.numberLength
              && (digit = ~negative.digits[i]) == 0; i++) {
            // empty
          }
          // digit = ~negative.digits[i] & ~0
          if (digit == 0) {
            resLength++;
            resDigits = new int[resLength];
            resDigits[resLength - 1] = 1;

            BigInteger result = new BigInteger(-1, resLength, resDigits);
            return result;
          }
        }
      }
      resDigits = new int[resLength];
      resDigits[i] = -digit;
      i++;
    }

    limit = Math.min(positive.numberLength, negative.numberLength);
    for (; i < limit; i++) {
      // resDigits[i] = ~(~negative.digits[i] & ~positive.digits[i]);
      resDigits[i] = negative.digits[i] | positive.digits[i];
    }
    // Actually one of the next two cycles will be executed
    for (; i < negative.numberLength; i++) {
      resDigits[i] = negative.digits[i];
    }
    for (; i < positive.numberLength; i++) {
      resDigits[i] = positive.digits[i];
    }

    BigInteger result = new BigInteger(-1, resLength, resDigits);
    return result;
  }

  /**
   * Return sign = 1, magnitude = val.magnitude & ~that.magnitude.
   * @param val
   * @param that
   * @return
   */
  static BigInteger andNotPositive(BigInteger val, BigInteger that) {
    // PRE: both arguments are positive
    int resDigits[] = new int[val.numberLength];

    int limit = Math.min(val.numberLength, that.numberLength);
    int i;
    for (i = val.getFirstNonzeroDigit(); i < limit; i++) {
      resDigits[i] = val.digits[i] & ~that.digits[i];
    }
    for (; i < val.numberLength; i++) {
      resDigits[i] = val.digits[i];
    }

    BigInteger result = new BigInteger(1, val.numberLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = 1, magnitude = positive.magnitude & ~(-negative.magnitude).
   * @param positive
   * @param negative
   * @return
   */
  static BigInteger andNotPositiveNegative(BigInteger positive,
      BigInteger negative) {
    // PRE: positive > 0 && negative < 0
    int iNeg = negative.getFirstNonzeroDigit();
    int iPos = positive.getFirstNonzeroDigit();

    if (iNeg >= positive.numberLength) {
      return positive;
    }

    int resLength = Math.min(positive.numberLength, negative.numberLength);
    int resDigits[] = new int[resLength];

    // Always start from first non zero of positive
    int i = iPos;
    for (; i < iNeg; i++) {
      // resDigits[i] = positive.digits[i] & -1 (~0)
      resDigits[i] = positive.digits[i];
    }
    if (i == iNeg) {
      resDigits[i] = positive.digits[i] & (negative.digits[i] - 1);
      i++;
    }
    for (; i < resLength; i++) {
      // resDigits[i] = positive.digits[i] & ~(~negative.digits[i]);
      resDigits[i] = positive.digits[i] & negative.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = 1, magnitude = val.magnitude & that.magnitude.
   * @param val
   * @param that
   * @return
   */
  static BigInteger andPositive(BigInteger val, BigInteger that) {
    // PRE: both arguments are positive
    int resLength = Math.min(val.numberLength, that.numberLength);
    int i = Math.max(val.getFirstNonzeroDigit(), that.getFirstNonzeroDigit());

    if (i >= resLength) {
      return BigInteger.ZERO;
    }

    int resDigits[] = new int[resLength];
    for (; i < resLength; i++) {
      resDigits[i] = val.digits[i] & that.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * @see BigInteger#not()
   * @param val
   * @return
   */
  static BigInteger not(BigInteger val) {
    if (val.sign == 0) {
      return BigInteger.MINUS_ONE;
    }
    if (val.equals(BigInteger.MINUS_ONE)) {
      return BigInteger.ZERO;
    }
    int resDigits[] = new int[val.numberLength + 1];
    int i;

    if (val.sign > 0) {
      // ~val = -val + 1
      if (val.digits[val.numberLength - 1] != -1) {
        for (i = 0; val.digits[i] == -1; i++) {
          // empty
        }
      } else {
        for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) {
          // empty
        }
        if (i == val.numberLength) {
          resDigits[i] = 1;
          return new BigInteger(-val.sign, i + 1, resDigits);
        }
      }
      // Here a carry 1 was generated
    } else {
      // (val.sign < 0)
      // ~val = -val - 1
      for (i = 0; val.digits[i] == 0; i++) {
        resDigits[i] = -1;
      }
      // Here a borrow -1 was generated
    }
    // Now, the carry/borrow can be absorbed
    resDigits[i] = val.digits[i] + val.sign;
    // Copying the remaining unchanged digit
    for (i++; i < val.numberLength; i++) {
      resDigits[i] = val.digits[i];
    }
    return new BigInteger(-val.sign, i, resDigits);
  }

  /**
   * @see BigInteger#or(BigInteger).
   * @param val
   * @param that
   * @return
   */
  static BigInteger or(BigInteger val, BigInteger that) {
    if (that.equals(BigInteger.MINUS_ONE) || val.equals(BigInteger.MINUS_ONE)) {
      return BigInteger.MINUS_ONE;
    }
    if (that.sign == 0) {
      return val;
    }
    if (val.sign == 0) {
      return that;
    }

    if (val.sign > 0) {
      if (that.sign > 0) {
        if (val.numberLength > that.numberLength) {
          return orPositive(val, that);
        } else {
          return orPositive(that, val);
        }
      } else {
        return orDiffSigns(val, that);
      }
    } else {
      if (that.sign > 0) {
        return orDiffSigns(that, val);
      } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
        return orNegative(that, val);
      } else {
        return orNegative(val, that);
      }
    }
  }

  /**
   * Return sign = -1, magnitude = -(positive.magnitude | -negative.magnitude).
   * @param positive
   * @param negative
   * @return
   */
  static BigInteger orDiffSigns(BigInteger positive, BigInteger negative) {
    // Jumping over the least significant zero bits
    int iNeg = negative.getFirstNonzeroDigit();
    int iPos = positive.getFirstNonzeroDigit();
    int i;
    int limit;

    // Look if the trailing zeros of the positive will "copy" all
    // the negative digits
    if (iPos >= negative.numberLength) {
      return negative;
    }
    int resLength = negative.numberLength;
    int resDigits[] = new int[resLength];

    if (iNeg < iPos) {
      // We know for sure that this will
      // be the first non zero digit in the result
      for (i = iNeg; i < iPos; i++) {
        resDigits[i] = negative.digits[i];
      }
    } else if (iPos < iNeg) {
      i = iPos;
      resDigits[i] = -positive.digits[i];
      limit = Math.min(positive.numberLength, iNeg);
      for (i++; i < limit; i++) {
        resDigits[i] = ~positive.digits[i];
      }
      if (i != positive.numberLength) {
        resDigits[i] = ~(-negative.digits[i] | positive.digits[i]);
      } else {
        for (; i < iNeg; i++) {
          resDigits[i] = -1;
        }
        // resDigits[i] = ~(-negative.digits[i] | 0);
        resDigits[i] = negative.digits[i] - 1;
      }
      i++;
    } else {
      // iNeg == iPos
      // Applying two complement to negative and to result
      i = iPos;
      resDigits[i] = -(-negative.digits[i] | positive.digits[i]);
      i++;
    }
    limit = Math.min(negative.numberLength, positive.numberLength);
    for (; i < limit; i++) {
      // Applying two complement to negative and to result
      // resDigits[i] = ~(~negative.digits[i] | positive.digits[i] );
      resDigits[i] = negative.digits[i] & ~positive.digits[i];
    }
    for (; i < negative.numberLength; i++) {
      resDigits[i] = negative.digits[i];
    }

    BigInteger result = new BigInteger(-1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = -1, magnitude = -(-val.magnitude | -that.magnitude).
   * @param val
   * @param that
   * @return
   */
  static BigInteger orNegative(BigInteger val, BigInteger that) {
    // PRE: val and that are negative;
    // PRE: val has at least as many trailing zeros digits as that
    int iThat = that.getFirstNonzeroDigit();
    int iVal = val.getFirstNonzeroDigit();
    int i;

    if (iVal >= that.numberLength) {
      return that;
    } else if (iThat >= val.numberLength) {
      return val;
    }

    int resLength = Math.min(val.numberLength, that.numberLength);
    int resDigits[] = new int[resLength];

    // Looking for the first non-zero digit of the result
    if (iThat == iVal) {
      resDigits[iVal] = -(-val.digits[iVal] | -that.digits[iVal]);
      i = iVal;
    } else {
      for (i = iThat; i < iVal; i++) {
        resDigits[i] = that.digits[i];
      }
      resDigits[i] = that.digits[i] & (val.digits[i] - 1);
    }

    for (i++; i < resLength; i++) {
      resDigits[i] = val.digits[i] & that.digits[i];
    }

    BigInteger result = new BigInteger(-1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = 1, magnitude = longer.magnitude | shorter.magnitude.
   * @param longer
   * @param shorter
   * @return
   */
  static BigInteger orPositive(BigInteger longer, BigInteger shorter) {
    // PRE: longer and shorter are positive;
    // PRE: longer has at least as many digits as shorter
    int resLength = longer.numberLength;
    int resDigits[] = new int[resLength];

    int i = Math.min(longer.getFirstNonzeroDigit(),
        shorter.getFirstNonzeroDigit());
    for (i = 0; i < shorter.numberLength; i++) {
      resDigits[i] = longer.digits[i] | shorter.digits[i];
    }
    for (; i < resLength; i++) {
      resDigits[i] = longer.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    return result;
  }

  /**
   * @see BigInteger#xor(BigInteger)
   * @param val
   * @param that
   * @return
   */
  static BigInteger xor(BigInteger val, BigInteger that) {
    if (that.sign == 0) {
      return val;
    }
    if (val.sign == 0) {
      return that;
    }
    if (that.equals(BigInteger.MINUS_ONE)) {
      return val.not();
    }
    if (val.equals(BigInteger.MINUS_ONE)) {
      return that.not();
    }

    if (val.sign > 0) {
      if (that.sign > 0) {
        if (val.numberLength > that.numberLength) {
          return xorPositive(val, that);
        } else {
          return xorPositive(that, val);
        }
      } else {
        return xorDiffSigns(val, that);
      }
    } else {
      if (that.sign > 0) {
        return xorDiffSigns(that, val);
      } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
        return xorNegative(that, val);
      } else {
        return xorNegative(val, that);
      }
    }
  }

  /**
   * Return sign = 1, magnitude = -(positive.magnitude ^ -negative.magnitude).
   * @param positive
   * @param negative
   * @return
   */
  static BigInteger xorDiffSigns(BigInteger positive, BigInteger negative) {
    int resLength = Math.max(negative.numberLength, positive.numberLength);
    int resDigits[];
    int iNeg = negative.getFirstNonzeroDigit();
    int iPos = positive.getFirstNonzeroDigit();
    int i;
    int limit;

    // The first
    if (iNeg < iPos) {
      resDigits = new int[resLength];
      i = iNeg;
      // resDigits[i] = -(-negative.digits[i]);
      resDigits[i] = negative.digits[i];
      limit = Math.min(negative.numberLength, iPos);
      // Skip the positive digits while they are zeros
      for (i++; i < limit; i++) {
        // resDigits[i] = ~(~negative.digits[i]);
        resDigits[i] = negative.digits[i];
      }
      // if the negative has no more elements, must fill the
      // result with the remaining digits of the positive
      if (i == negative.numberLength) {
        for (; i < positive.numberLength; i++) {
          // resDigits[i] = ~(positive.digits[i] ^ -1) -> ~(~positive.digits[i])
          resDigits[i] = positive.digits[i];
        }
      }
    } else if (iPos < iNeg) {
      resDigits = new int[resLength];
      i = iPos;
      // Applying two complement to the first non-zero digit of the result
      resDigits[i] = -positive.digits[i];
      limit = Math.min(positive.numberLength, iNeg);
      for (i++; i < limit; i++) {
        // Continue applying two complement the result
        resDigits[i] = ~positive.digits[i];
      }
      // When the first non-zero digit of the negative is reached, must apply
      // two complement (arithmetic negation) to it, and then operate
      if (i == iNeg) {
        resDigits[i] = ~(positive.digits[i] ^ -negative.digits[i]);
        i++;
      } else {
        // if the positive has no more elements must fill the remaining digits
        // with
        // the negative ones
        for (; i < iNeg; i++) {
          // resDigits[i] = ~(0 ^ 0)
          resDigits[i] = -1;
        }
        for (; i < negative.numberLength; i++) {
          // resDigits[i] = ~(~negative.digits[i] ^ 0)
          resDigits[i] = negative.digits[i];
        }
      }
    } else {
      int digit;
      // The first non-zero digit of the positive and negative are the same
      i = iNeg;
      digit = positive.digits[i] ^ -negative.digits[i];
      if (digit == 0) {
        limit = Math.min(positive.numberLength, negative.numberLength);
        for (i++; i < limit
            && (digit = positive.digits[i] ^ ~negative.digits[i]) == 0; i++) {
          // empty
        }
        if (digit == 0) {
          // shorter has only the remaining virtual sign bits
          for (; i < positive.numberLength
              && (digit = ~positive.digits[i]) == 0; i++) {
            // empty
          }
          for (; i < negative.numberLength
              && (digit = ~negative.digits[i]) == 0; i++) {
            // empty
          }
          if (digit == 0) {
            resLength = resLength + 1;
            resDigits = new int[resLength];
            resDigits[resLength - 1] = 1;

            BigInteger result = new BigInteger(-1, resLength, resDigits);
            return result;
          }
        }
      }
      resDigits = new int[resLength];
      resDigits[i] = -digit;
      i++;
    }

    limit = Math.min(negative.numberLength, positive.numberLength);
    for (; i < limit; i++) {
      resDigits[i] = ~(~negative.digits[i] ^ positive.digits[i]);
    }
    for (; i < positive.numberLength; i++) {
      // resDigits[i] = ~(positive.digits[i] ^ -1)
      resDigits[i] = positive.digits[i];
    }
    for (; i < negative.numberLength; i++) {
      // resDigits[i] = ~(0 ^ ~negative.digits[i])
      resDigits[i] = negative.digits[i];
    }

    BigInteger result = new BigInteger(-1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = 0, magnitude = -val.magnitude ^ -that.magnitude.
   * @param val
   * @param that
   * @return
   */
  static BigInteger xorNegative(BigInteger val, BigInteger that) {
    // PRE: val and that are negative
    // PRE: val has at least as many trailing zero digits as that
    int resLength = Math.max(val.numberLength, that.numberLength);
    int resDigits[] = new int[resLength];
    int iVal = val.getFirstNonzeroDigit();
    int iThat = that.getFirstNonzeroDigit();
    int i = iThat;
    int limit;

    if (iVal == iThat) {
      resDigits[i] = -val.digits[i] ^ -that.digits[i];
    } else {
      resDigits[i] = -that.digits[i];
      limit = Math.min(that.numberLength, iVal);
      for (i++; i < limit; i++) {
        resDigits[i] = ~that.digits[i];
      }
      // Remains digits in that?
      if (i == that.numberLength) {
        // Jumping over the remaining zero to the first non one
        for (; i < iVal; i++) {
          // resDigits[i] = 0 ^ -1;
          resDigits[i] = -1;
        }
        // resDigits[i] = -val.digits[i] ^ -1;
        resDigits[i] = val.digits[i] - 1;
      } else {
        resDigits[i] = -val.digits[i] ^ ~that.digits[i];
      }
    }

    limit = Math.min(val.numberLength, that.numberLength);
    // Perform ^ between that al val until that ends
    for (i++; i < limit; i++) {
      // resDigits[i] = ~val.digits[i] ^ ~that.digits[i];
      resDigits[i] = val.digits[i] ^ that.digits[i];
    }
    // Perform ^ between val digits and -1 until val ends
    for (; i < val.numberLength; i++) {
      // resDigits[i] = ~val.digits[i] ^ -1 ;
      resDigits[i] = val.digits[i];
    }
    for (; i < that.numberLength; i++) {
      // resDigits[i] = -1 ^ ~that.digits[i] ;
      resDigits[i] = that.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Return sign = 0, magnitude = longer.magnitude | shorter.magnitude.
   * 
   * @param longer
   * @param shorter
   * @return
   */
  static BigInteger xorPositive(BigInteger longer, BigInteger shorter) {
    // PRE: longer and shorter are positive;
    // PRE: longer has at least as many digits as shorter
    int resLength = longer.numberLength;
    int resDigits[] = new int[resLength];
    int i = Math.min(longer.getFirstNonzeroDigit(),
        shorter.getFirstNonzeroDigit());
    for (; i < shorter.numberLength; i++) {
      resDigits[i] = longer.digits[i] ^ shorter.digits[i];
    }
    for (; i < longer.numberLength; i++) {
      resDigits[i] = longer.digits[i];
    }

    BigInteger result = new BigInteger(1, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Just to denote that this class can't be instantiated.
   */
  private Logical() {
  }
}
