internal static EInteger FindPowerOfTenFromBig(EInteger bigintExponent) { int sign = bigintExponent.Sign; if (sign < 0) { return(EInteger.Zero); } if (sign == 0) { return(EInteger.One); } if (bigintExponent.CompareTo(ValueBigInt36) <= 0) { return(FindPowerOfTen((int)bigintExponent)); } FastInteger intcurexp = FastInteger.FromBig(bigintExponent); EInteger mantissa = EInteger.One; EInteger bigpow = EInteger.Zero; // DebugUtility.Log("Getting power of ten from big "+bigintExponent); while (intcurexp.Sign > 0) { if (intcurexp.CompareToInt(18) <= 0) { bigpow = FindPowerOfTen(intcurexp.AsInt32()); mantissa *= (EInteger)bigpow; break; } if (intcurexp.CompareToInt(9999999) <= 0) { int val = intcurexp.AsInt32(); bigpow = FindPowerOfFive(val); bigpow <<= val; mantissa *= (EInteger)bigpow; break; } if (bigpow.IsZero) { bigpow = FindPowerOfFive(9999999); bigpow <<= 9999999; } mantissa *= bigpow; intcurexp.AddInt(-9999999); } return(mantissa); }
public int CompareTo(FastInteger fint) { switch (this.integerMode) { case IntegerMode.SmallValue: return(-fint.CompareToInt(this.smallValue)); case IntegerMode.LargeValue: return(-fint.CompareTo(this.largeValue)); default: throw new InvalidOperationException(); } }
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); }
internal static EInteger FindPowerOfFiveFromBig(EInteger diff) { int sign = diff.Sign; if (sign < 0) { return(EInteger.Zero); } if (sign == 0) { return(EInteger.One); } FastInteger intcurexp = FastInteger.FromBig(diff); if (intcurexp.CompareToInt(54) <= 0) { return(FindPowerOfFive(intcurexp.AsInt32())); } EInteger mantissa = EInteger.One; EInteger bigpow; EInteger origdiff = diff; bigpow = ValuePowerOfFiveCache.GetCachedPower(origdiff); if (bigpow != null) { return(bigpow); } EInteger[] otherPower = ValuePowerOfFiveCache.FindCachedPowerOrSmaller(origdiff); if (otherPower != null) { intcurexp.SubtractBig(otherPower[0]); bigpow = otherPower[1]; mantissa = bigpow; } else { bigpow = EInteger.Zero; } while (intcurexp.Sign > 0) { if (intcurexp.CompareToInt(27) <= 0) { bigpow = FindPowerOfFive(intcurexp.AsInt32()); mantissa *= (EInteger)bigpow; break; } if (intcurexp.CompareToInt(9999999) <= 0) { bigpow = FindPowerOfFive(1).Pow(intcurexp.AsInt32()); mantissa *= (EInteger)bigpow; break; } if (bigpow.IsZero) { bigpow = FindPowerOfFive(1).Pow(9999999); } mantissa *= bigpow; intcurexp.AddInt(-9999999); } ValuePowerOfFiveCache.AddPower(origdiff, mantissa); return(mantissa); }
private void ShiftToDigitsBig(int digits, bool truncate) { // Shifts a number until it reaches the given number of digits, // gathering information on whether the last digit discarded is set // and whether the discarded digits to the right of that digit are set. // Assumes that the big integer being shifted is positive. if (this.knownDigitLength != null) { if (this.knownDigitLength.CompareToInt(digits) <= 0) { return; } } string str; this.knownDigitLength = this.knownDigitLength ?? this.CalcKnownDigitLength(); if (this.knownDigitLength.CompareToInt(digits) <= 0) { return; } FastInteger digitDiff = this.knownDigitLength.Copy().SubtractInt(digits); if (truncate && digitDiff.CanFitInInt32()) { this.TruncateRight(digitDiff); return; } if (digitDiff.CompareToInt(1) == 0) { EInteger bigrem; EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem(ValueTen); bigquo = divrem[0]; bigrem = divrem[1]; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (int)bigrem; this.shiftedBigInt = bigquo; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.Add(digitDiff); this.UpdateKnownLength(digitDiff); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; return; } if (digitDiff.CompareToInt(9) <= 0) { EInteger bigrem; int diffInt = digitDiff.AsInt32(); EInteger radixPower = NumberUtility.FindPowerOfTen(diffInt); EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem(radixPower); bigquo = divrem[0]; bigrem = divrem[1]; var rem = (int)bigrem; this.bitsAfterLeftmost |= this.bitLeftmost; for (var i = 0; i < diffInt; ++i) { if (i == diffInt - 1) { this.bitLeftmost = rem % 10; } else { int intQuot = (rem < 43698) ? ((rem * 26215) >> 18) : (rem / 10); this.bitsAfterLeftmost |= rem - (intQuot * 10); rem = intQuot; } } this.shiftedBigInt = bigquo; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.Add(digitDiff); this.UpdateKnownLength(digitDiff); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; return; } if (digitDiff.CanFitInInt32()) { #if DEBUG if (!(digitDiff.CompareToInt(2) > 0)) { throw new ArgumentException( "doesn't satisfy digitDiff.CompareToInt(2)>0"); } #endif EInteger bigrem = null; EInteger bigquo; EInteger[] divrem; if (!this.shiftedBigInt.IsEven || this.bitsAfterLeftmost != 0) { EInteger radixPower = NumberUtility.FindPowerOfTen(digitDiff.AsInt32() - 1); this.bitsAfterLeftmost |= 1; bigquo = this.shiftedBigInt.Divide(radixPower); } else { EInteger radixPower = NumberUtility.FindPowerOfTen(digitDiff.AsInt32() - 1); divrem = this.shiftedBigInt.DivRem(radixPower); bigquo = divrem[0]; bigrem = divrem[1]; this.bitsAfterLeftmost |= this.bitLeftmost; if (!bigrem.IsZero) { this.bitsAfterLeftmost |= 1; } } EInteger bigquo2; divrem = bigquo.DivRem(ValueTen); bigquo2 = divrem[0]; bigrem = divrem[1]; this.bitLeftmost = (int)bigrem; this.shiftedBigInt = bigquo2; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.Add(digitDiff); this.UpdateKnownLength(digitDiff); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; return; } str = this.shiftedBigInt.ToString(); // NOTE: Will be 1 if the value is 0 int digitLength = str.Length; this.knownDigitLength = new FastInteger(digitLength); // Shift by the difference in digit length if (digitLength > digits) { int digitShift = digitLength - digits; this.UpdateKnownLengthInt(digitShift); var newLength = (int)(digitLength - digitShift); // Console.WriteLine("dlen= " + digitLength + " dshift=" + // digitShift + " newlen= " + newLength); this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); if (digitShift <= Int32.MaxValue) { this.discardedBitCount.AddInt((int)digitShift); } else { this.discardedBitCount.AddBig((EInteger)digitShift); } for (int i = str.Length - 1; i >= 0; --i) { this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (int)(str[i] - '0'); --digitShift; if (digitShift <= 0) { break; } } if (newLength <= 9) { this.isSmall = true; this.shiftedSmall = FastParseLong(str, 0, newLength); } else { this.shiftedBigInt = EInteger.FromSubstring(str, 0, newLength); } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; } }
internal static EInteger FindPowerOfFiveFromBig(EInteger diff) { int sign = diff.Sign; if (sign < 0) { return(EInteger.Zero); } if (sign == 0) { return(EInteger.One); } FastInteger intcurexp = FastInteger.FromBig(diff); if (intcurexp.CompareToInt(54) <= 0) { return(FindPowerOfFive(intcurexp.AsInt32())); } // DebugUtility.Log("Getting power of five from big "+diff); EInteger mantissa = EInteger.One; EInteger bigpow; EInteger origdiff = diff; bigpow = ValuePowerOfFiveCache.GetCachedPower(origdiff); if (bigpow != null) { return(bigpow); } EInteger[] otherPower = ValuePowerOfFiveCache.FindCachedPowerOrSmaller(origdiff); if (otherPower != null) { // DebugUtility.Log("Found cached power " +otherPower[0]+", " // +otherPower[1]); intcurexp.SubtractBig(otherPower[0]); bigpow = otherPower[1]; mantissa = bigpow; } else { bigpow = EInteger.Zero; } while (intcurexp.Sign > 0) { if (intcurexp.CompareToInt(27) <= 0) { bigpow = FindPowerOfFive(intcurexp.AsInt32()); mantissa *= (EInteger)bigpow; break; } if (intcurexp.CompareToInt(9999999) <= 0) { int icurexp = intcurexp.AsInt32(); int halficurexp = icurexp / 2; bigpow = FindPowerOfFive(halficurexp); bigpow = bigpow.Multiply( FindPowerOfFive(icurexp - halficurexp)); mantissa *= (EInteger)bigpow; break; } if (bigpow.IsZero) { bigpow = FindPowerOfFive(1).Pow(9999999); } mantissa *= bigpow; intcurexp.AddInt(-9999999); } ValuePowerOfFiveCache.AddPower(origdiff, mantissa); return(mantissa); }