public static EInteger ReduceTrailingZeros( EInteger bigmant, FastInteger exponentMutable, int radix, FastInteger digits, FastInteger precision, FastInteger idealExp) { #if DEBUG if (precision != null && digits == null) { throw new ArgumentException("doesn't satisfy precision==null || digits!=null"); } #endif if (bigmant.IsZero) { exponentMutable.SetInt(0); return bigmant; } var bigradix = (EInteger)radix; var bitToTest = 0; var bitsToShift = new FastInteger(0); while (!bigmant.IsZero) { if (precision != null && digits.CompareTo(precision) == 0) { break; } if (idealExp != null && exponentMutable.CompareTo(idealExp) == 0) { break; } if (radix == 2) { if (bitToTest < Int32.MaxValue) { if (bigmant.GetSignedBit(bitToTest)) { break; } ++bitToTest; bitsToShift.Increment(); } else { if (!bigmant.IsEven) { break; } bigmant >>= 1; } } else { EInteger bigrem; EInteger bigquo; { EInteger[] divrem = bigmant.DivRem(bigradix); bigquo = divrem[0]; bigrem = divrem[1]; } if (!bigrem.IsZero) { break; } bigmant = bigquo; } exponentMutable.Increment(); if (digits != null) { digits.Decrement(); } } if (radix == 2 && !bitsToShift.IsValueZero) { while (bitsToShift.CompareToInt(1000000) > 0) { bigmant >>= 1000000; bitsToShift.SubtractInt(1000000); } int tmpshift = bitsToShift.AsInt32(); bigmant >>= tmpshift; } return bigmant; }
public static EInteger ReduceTrailingZeros( EInteger bigmant, FastInteger exponentMutable, int radix, FastInteger digits, FastInteger precision, FastInteger idealExp) { #if DEBUG if (precision != null && digits == null) { throw new ArgumentException("doesn't satisfy precision==null ||" + "\u0020digits!=null"); } if (!(bigmant.Sign >= 0)) { throw new ArgumentException("doesn't satisfy bigmant.Sign >= 0"); } #endif if (bigmant.IsZero) { exponentMutable.SetInt(0); return(bigmant); } if (radix == 2) { if (!bigmant.IsEven) { return(bigmant); } long lowbit = bigmant.GetLowBitAsInt64(); if (lowbit != Int64.MaxValue) { if (precision != null && digits.CompareTo(precision) >= 0) { // Limit by digits minus precision EInteger tmp = digits.ToEInteger().Subtract(precision.ToEInteger()); if (tmp.CompareTo(EInteger.FromInt64(lowbit)) < 0) { lowbit = tmp.ToInt64Checked(); } } if (idealExp != null && exponentMutable.CompareTo(idealExp) <= 0) { // Limit by idealExp minus exponentMutable EInteger tmp = idealExp.ToEInteger().Subtract(exponentMutable.ToEInteger()); if (tmp.CompareTo(EInteger.FromInt64(lowbit)) < 0) { lowbit = tmp.ToInt64Checked(); } } bigmant = (lowbit <= Int32.MaxValue) ? bigmant.ShiftRight((int)lowbit) : bigmant.ShiftRight(EInteger.FromInt64(lowbit)); if (digits != null) { digits.SubtractInt64(lowbit); } if (exponentMutable != null) { exponentMutable.AddInt64(lowbit); } return(bigmant); } } var bigradix = (EInteger)radix; var bitsToShift = new FastInteger(0); while (!bigmant.IsZero) { if (precision != null && digits.CompareTo(precision) == 0) { break; } if (idealExp != null && exponentMutable.CompareTo(idealExp) == 0) { break; } EInteger bigrem; EInteger bigquo; EInteger[] divrem = bigmant.DivRem(bigradix); bigquo = divrem[0]; bigrem = divrem[1]; if (!bigrem.IsZero) { break; } bigmant = bigquo; exponentMutable.Increment(); if (digits != null) { digits.Decrement(); } } return(bigmant); }
private static FastInteger ByteArrayBitLength(byte[] bytes) { FastInteger fastKB = new FastInteger(bytes.Length).Multiply(8); for (int i = bytes.Length - 1; i >= 0; i--) { int b = (int)bytes[i]; if (b != 0) { if ((b & 0x80) != 0) { break; } if ((b & 0x40) != 0) { fastKB.Decrement(); break; } if ((b & 0x20) != 0) { fastKB.SubtractInt(2); break; } if ((b & 0x10) != 0) { fastKB.SubtractInt(3); break; } if ((b & 0x08) != 0) { fastKB.SubtractInt(4); break; } if ((b & 0x04) != 0) { fastKB.SubtractInt(5); break; } if ((b & 0x02) != 0) { fastKB.SubtractInt(6); break; } if ((b & 0x01) != 0) { fastKB.SubtractInt(7); break; } } fastKB.SubtractInt(8); } // Make sure bit length is 1 if value is 0 if (fastKB.Sign == 0) fastKB.Increment(); return fastKB; }