internal static int bitCount(BigInteger val) { int bCount = 0; if (val.sign == 0) { return(0); } int i = val.getFirstNonzeroDigit();; if (val.sign > 0) { for ( ; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(val.digits[i]); } } else // (sign < 0) // this digit absorbs the carry { bCount += BigDecimal.bitCount(-val.digits[i]); for (i++; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(~val.digits[i]); } // We take the complement sum: bCount = (val.numberLength << 5) - bCount; } return(bCount); }
internal static BigInteger andDiffSigns(BigInteger positive, BigInteger 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; }
internal 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)); } } }
internal static BigInteger andNegative(BigInteger longer, BigInteger 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++) ; if (digit == 0) { resLength = longer.numberLength + 1; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return new BigInteger(-1, resLength, resDigits); } } } 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; }
internal static BigInteger orNegative(BigInteger val, BigInteger 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); }
internal static BigInteger andDiffSigns(BigInteger positive, BigInteger 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); }
internal static BigInteger flipBit(BigInteger val, int n) { int resSign = (val.sign == 0) ? 1 : val.sign; int intCount = n >> 5; int bitN = n & 31; int resLength = Math.Max(intCount + 1, val.numberLength) + 1; int[] resDigits = new int[resLength]; int i; int bitNumber = 1 << bitN; Array.Copy(val.digits, 0, resDigits, 0, val.numberLength); if (val.sign < 0) { if (intCount >= val.numberLength) { resDigits[intCount] = bitNumber; } else { //val.sign<0 y intCount < val.numberLength int firstNonZeroDigit = val.getFirstNonzeroDigit(); if (intCount > firstNonZeroDigit) { resDigits[intCount] ^= bitNumber; } else if (intCount < firstNonZeroDigit) { resDigits[intCount] = -bitNumber; for (i=intCount + 1; i < firstNonZeroDigit; i++) { resDigits[i]=-1; } resDigits[i] = resDigits[i]--; } else { i = intCount; resDigits[i] = -((-resDigits[intCount]) ^ bitNumber); if (resDigits[i] == 0) { for (i++; resDigits[i] == -1 ; i++) { resDigits[i] = 0; } resDigits[i]++; } } } } else {//case where val is positive resDigits[intCount] ^= bitNumber; } BigInteger result = new BigInteger(resSign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; }
internal static int bitLength(BigInteger val) { if (val.sign == 0) { return 0; } int bLength = (val.numberLength << 5); int highDigit = val.digits[val.numberLength - 1]; if (val.sign < 0) { int i = val.getFirstNonzeroDigit(); // We reduce the problem to the positive case. if (i == val.numberLength - 1) { highDigit--; } } // Subtracting all sign bits bLength -= BigDecimal.numberOfLeadingZeros(highDigit); return bLength; }
internal static BigInteger xorPositive(BigInteger longer, BigInteger 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); }
internal 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); }
internal 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); }
internal 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); }
internal static int bitLength(BigInteger val) { if (val.sign == 0) { return(0); } int bLength = (val.numberLength << 5); int highDigit = val.digits[val.numberLength - 1]; if (val.sign < 0) { int i = val.getFirstNonzeroDigit(); // We reduce the problem to the positive case. if (i == val.numberLength - 1) { highDigit--; } } // Subtracting all sign bits bLength -= BigDecimal.numberOfLeadingZeros(highDigit); return(bLength); }
internal static int bitCount(BigInteger val) { int bCount = 0; if (val.sign == 0) { return 0; } int i = val.getFirstNonzeroDigit();; if (val.sign > 0) { for ( ; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(val.digits[i]); } } else {// (sign < 0) // this digit absorbs the carry bCount += BigDecimal.bitCount(-val.digits[i]); for (i++; i < val.numberLength; i++) { bCount += BigDecimal.bitCount(~val.digits[i]); } // We take the complement sum: bCount = (val.numberLength << 5) - bCount; } return bCount; }
internal 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++) { ; } if (digit == 0) { // shorter has only the remaining virtual sign bits for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) { ; } for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) { ; } if (digit == 0) { resLength = resLength + 1; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return(new BigInteger(-1, resLength, resDigits)); } } } 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); }
internal static BigInteger xorPositive(BigInteger longer, BigInteger 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; }
internal static BigInteger andNegative(BigInteger longer, BigInteger 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++) { ; } if (digit == 0) { resLength = longer.numberLength + 1; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return(new BigInteger(-1, resLength, resDigits)); } } } 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); }
internal 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++) ; if (digit == 0) { // shorter has only the remaining virtual sign bits for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) ; for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) ; if (digit == 0) { resLength = resLength + 1; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return new BigInteger(-1, resLength, resDigits); } } } 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; }
internal static BigInteger xorNegative(BigInteger val, BigInteger 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; }
internal static BigInteger orNegative(BigInteger val, BigInteger 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; }
internal 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); } } }
internal 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; }
internal static BigInteger andNotNegativePositive(BigInteger negative, BigInteger positive) { 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++) { ; // digit = ~negative.digits[i] & ~0 } if (digit == 0) { resLength++; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return(new BigInteger(-1, resLength, resDigits)); } } } 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); }
internal 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; }
internal 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; }
internal 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; }
internal static BigInteger andNotNegativePositive(BigInteger negative, BigInteger positive) { 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++) ; // digit = ~negative.digits[i] & ~0 if (digit == 0) { resLength++; resDigits = new int[resLength]; resDigits[resLength - 1] = 1; return new BigInteger(-1, resLength, resDigits); } } } 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; }
internal static BigInteger andNotNegative(BigInteger val, BigInteger that) { 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); }
internal 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); }
internal static BigInteger xorNegative(BigInteger val, BigInteger 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); }
internal static BigInteger andNotNegative(BigInteger val, BigInteger that) { 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; }
internal static BigInteger flipBit(BigInteger val, int n) { int resSign = (val.sign == 0) ? 1 : val.sign; int intCount = n >> 5; int bitN = n & 31; int resLength = Math.Max(intCount + 1, val.numberLength) + 1; int[] resDigits = new int[resLength]; int i; int bitNumber = 1 << bitN; Array.Copy(val.digits, 0, resDigits, 0, val.numberLength); if (val.sign < 0) { if (intCount >= val.numberLength) { resDigits[intCount] = bitNumber; } else { //val.sign<0 y intCount < val.numberLength int firstNonZeroDigit = val.getFirstNonzeroDigit(); if (intCount > firstNonZeroDigit) { resDigits[intCount] ^= bitNumber; } else if (intCount < firstNonZeroDigit) { resDigits[intCount] = -bitNumber; for (i = intCount + 1; i < firstNonZeroDigit; i++) { resDigits[i] = -1; } resDigits[i] = resDigits[i]--; } else { i = intCount; resDigits[i] = -((-resDigits[intCount]) ^ bitNumber); if (resDigits[i] == 0) { for (i++; resDigits[i] == -1; i++) { resDigits[i] = 0; } resDigits[i]++; } } } } else //case where val is positive { resDigits[intCount] ^= bitNumber; } BigInteger result = new BigInteger(resSign, resLength, resDigits); result.cutOffLeadingZeroes(); return(result); }