All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.emul.java.math.Logical Maven / Gradle / Ivy

There is a newer version: 2.12.1
Show newest version
/*
 * 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. 
  • not
  • and *
  • andNot
  • or
  • xor
*/ 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() { } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy