public static void TestStringEqualRoundTrip(EInteger obj) { string str = obj.ToString(); EInteger newobj = EInteger.FromString(str); string str2 = newobj.ToString(); TestCommon.AssertEqualsHashCode(obj, newobj); TestCommon.AssertEqualsHashCode(str, str2); }
public CBORObject GetObject(EInteger bigIndex) { if (bigIndex.Sign < 0) { throw new CBORException("Unexpected index"); } if (!bigIndex.CanFitInInt32()) { throw new CBORException("Index " + bigIndex + " is bigger than supported "); } var index = (int)bigIndex; if (index >= this.sharedObjects.Count) { throw new CBORException("Index " + index + " is not valid"); } return this.sharedObjects[index]; }
public DigitShiftAccumulator( EInteger bigint, int lastDiscarded, int olderDiscarded) { if (bigint.CanFitInInt32()) { this.shiftedSmall = (int)bigint; if (this.shiftedSmall < 0) { throw new ArgumentException("shiftedSmall (" + this.shiftedSmall + ") is less than 0"); } this.isSmall = true; } else { this.shiftedBigInt = bigint; this.isSmall = false; } this.bitsAfterLeftmost = (olderDiscarded != 0) ? 1 : 0; this.bitLeftmost = lastDiscarded; }
public EInteger[] FindCachedPowerIntOrSmaller(int precision) { EInteger[] ret = null; var integerMinValue = -1; lock (this.outputs) { for (var i = 0; i < this.size; ++i) { if (this.inputsInts[i] >= 0 && this.inputsInts[i] <= precision && (integerMinValue == -1 || this.inputsInts[i] >= integerMinValue)) { // DebugUtility.Log("Have cached power (" + inputs[i] + "," + bi + ") "); ret = new EInteger[2]; ret[0] = this.inputs[i]; ret[1] = this.outputs[i]; integerMinValue = this.inputsInts[i]; } } } return ret; }
internal static EInteger ShiftLeftInt(EInteger val, int shift) { #if DEBUG if (val == null) { throw new ArgumentNullException("val"); } #endif if (val.IsZero) { return val; } while (shift > 1000000) { val <<= 1000000; shift -= 1000000; } var lastshift = (int)shift; val <<= lastshift; return val; }
public static string BigIntToString(EInteger bigint) { return bigint.ToString(); }
public static void TestMultiplyDivideOne( EInteger bigintA, EInteger bigintB) { // Test that A*B/A = B and A*B/B = A try { EInteger bigintRem; EInteger bigintE; EInteger bigintD; EInteger bigintC = bigintA.Multiply (bigintB); TestCommon.CompareTestEqualAndConsistent ( bigintC, bigintB.Multiply (bigintA)); if (!bigintB.IsZero) { { EInteger [] divrem = bigintC.DivRem (bigintB); bigintD = divrem [0]; bigintRem = divrem [1]; } TestCommon.CompareTestEqualAndConsistent (bigintD, bigintA); TestCommon.CompareTestEqual (EInteger.Zero, bigintRem); bigintE = bigintC.Divide (bigintB); // Testing that DivRem and division method return // the same value TestCommon.CompareTestEqualAndConsistent (bigintD, bigintE); bigintE = bigintC.Remainder (bigintB); TestCommon.CompareTestEqualAndConsistent (bigintRem, bigintE); if (bigintE.Sign > 0 && !bigintC.Mod (bigintB).Equals (bigintE)) { TestCommon.CompareTestEqualAndConsistent ( bigintE, bigintC.Mod (bigintB)); } } if (!bigintA.IsZero) { EInteger [] divrem = bigintC.DivRem (bigintA); bigintD = divrem [0]; bigintRem = divrem [1]; TestCommon.CompareTestEqualAndConsistent (bigintD, bigintB); TestCommon.CompareTestEqual (EInteger.Zero, bigintRem); } if (!bigintB.IsZero) { EInteger [] divrem = bigintA.DivRem (bigintB); bigintC = divrem [0]; bigintRem = divrem [1]; bigintD = bigintB.Multiply (bigintC); bigintD += (EInteger)bigintRem; TestCommon.CompareTestEqualAndConsistent (bigintA, bigintD); } // ----------------------------------- // EDecimal // ----------------------------------- EDecimal edecA = EDecimal.FromEInteger (bigintA); EDecimal edecB = EDecimal.FromEInteger (bigintB); EDecimal edecC = edecA.Multiply (edecB); EDecimal edecRem; EDecimal edecE; EDecimal edecD; TestCommon.CompareTestEqualAndConsistent ( edecC, edecB.Multiply (edecA)); if (!edecB.IsZero) { EDecimal [] divrem = edecC.DivRemNaturalScale (edecB); edecD = divrem [0].Plus (null); edecRem = divrem [1]; TestCommon.CompareTestEqualAndConsistent (edecD, edecA); TestCommon.CompareTestEqual (EDecimal.Zero, edecRem); edecE = edecC.DivideToExponent (edecB, 0, ERounding.Down); // Testing that DivRemNaturalScale and division method return // the same value TestCommon.CompareTestEqualAndConsistent (edecD, edecE); edecE = edecC.RemainderNaturalScale (edecB, null); TestCommon.CompareTestEqualAndConsistent (edecRem, edecE); } if (!edecA.IsZero) { EDecimal [] divrem = edecC.DivRemNaturalScale (edecA); edecD = divrem [0].Plus (null); edecRem = divrem [1]; TestCommon.CompareTestEqualAndConsistent (edecD, edecB); TestCommon.CompareTestEqual (EDecimal.Zero, edecRem); } if (!edecB.IsZero) { EDecimal [] divrem = edecA.DivRemNaturalScale (edecB); edecC = divrem [0].Plus (null); edecRem = divrem [1]; edecD = edecB.Multiply (edecC); edecD = edecD.Add (edecRem); TestCommon.CompareTestEqualAndConsistent (edecA, edecD); } // ----------------------------------- // EFloat // ----------------------------------- EFloat efloatA = EFloat.FromEInteger (bigintA); EFloat efloatB = EFloat.FromEInteger (bigintB); EFloat efloatC = efloatA.Multiply (efloatB); EFloat efloatRem; EFloat efloatE; EFloat efloatD; TestCommon.CompareTestEqualAndConsistent ( efloatC, efloatB.Multiply (efloatA)); if (!efloatB.IsZero) { EFloat [] divrem = efloatC.DivRemNaturalScale (efloatB); efloatD = divrem [0].Plus (null); efloatRem = divrem [1]; TestCommon.CompareTestEqualAndConsistent (efloatD, efloatA); TestCommon.CompareTestEqual (EFloat.Zero, efloatRem); efloatE = efloatC.DivideToExponent (efloatB, 0, ERounding.Down); // Testing that DivRemNaturalScale and division method return // the same value TestCommon.CompareTestEqualAndConsistent (efloatD, efloatE); efloatE = efloatC.RemainderNaturalScale (efloatB, null); TestCommon.CompareTestEqualAndConsistent (efloatRem, efloatE); } if (!efloatA.IsZero) { EFloat [] divrem = efloatC.DivRemNaturalScale (efloatA); efloatD = divrem [0].Plus (null); efloatRem = divrem [1]; TestCommon.CompareTestEqualAndConsistent (efloatD, efloatB); TestCommon.CompareTestEqual (EFloat.Zero, efloatRem); } if (!efloatB.IsZero) { EFloat [] divrem = efloatA.DivRemNaturalScale (efloatB); efloatC = divrem [0].Plus (null); efloatRem = divrem [1]; efloatD = efloatB.Multiply (efloatC); efloatD = efloatD.Add (efloatRem); TestCommon.CompareTestEqualAndConsistent (efloatA, efloatD); } } catch (Exception ex) { string testLine = "TestMultiplyDivideOne (\nEInteger.FromRadixString (\"" + bigintA.ToRadixString (16) + "\",16),\nEInteger.FromRadixString (\"" + bigintB.ToRadixString (16) + "\",16));"; Console.WriteLine(testLine); throw new InvalidOperationException(ex.Message + "\n"+testLine,ex); } }
public static void AssertBigIntegersEqual(string a, EInteger b) { Assert.AreEqual(a, b.ToString()); EInteger a2 = BigFromString(a); TestCommon.CompareTestEqualAndConsistent(a2, b); TestCommon.AssertEqualsHashCode(a2, b); }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EContext.#ctor(System.Int32,PeterO.Numbers.ERounding,System.Int32,System.Int32,System.Boolean)"]/*'/> public EContext( int precision, ERounding rounding, int exponentMinSmall, int exponentMaxSmall, bool clampNormalExponents) { if (precision < 0) { throw new ArgumentException("precision (" + precision + ") is less than 0"); } if (exponentMinSmall > exponentMaxSmall) { throw new ArgumentException("exponentMinSmall (" + exponentMinSmall + ") is more than " + exponentMaxSmall); } this.bigintPrecision = precision == 0 ? EInteger.Zero : (EInteger)precision; this.rounding = rounding; this.clampNormalExponents = clampNormalExponents; this.hasExponentRange = true; this.adjustExponent = true; this.exponentMax = exponentMaxSmall == 0 ? EInteger.Zero : (EInteger)exponentMaxSmall; this.exponentMin = exponentMinSmall == 0 ? EInteger.Zero : (EInteger)exponentMinSmall; }
public static ERational FromUInt64(ulong inputUInt64) { return(FromEInteger(EInteger.FromUInt64(inputUInt64))); }
public void ShiftToDigits( FastInteger bits, FastInteger preShift, bool truncate) { if (bits.Sign < 0) { throw new ArgumentException("bits's sign(" + bits.Sign + ") is less than 0"); } if (preShift != null && preShift.Sign > 0) { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" + // (//kbl) + " [" + this.shiftedBigInt + "]"); if (this.knownBitLength.CompareTo(bits) <= 0) { // Known digit length is already small enough // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(preShift); this.VerifyKnownLength(); return; } else { FastInteger bitDiff = this.knownBitLength.Copy() .Subtract(bits); // DebugUtility.Log("bitDiff=" + bitDiff); int cmp = bitDiff.CompareTo(preShift); if (cmp <= 0) { // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(preShift); this.VerifyKnownLength(); return; } else { // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(bitDiff); this.VerifyKnownLength(); return; } } } if (bits.CanFitInInt32()) { this.ShiftToDigitsInt(bits.AsInt32()); this.VerifyKnownLength(); } else { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); EInteger bigintDiff = this.knownBitLength.AsEInteger(); EInteger bitsBig = bits.AsEInteger(); bigintDiff -= (EInteger)bitsBig; if (bigintDiff.Sign > 0) { // current length is greater than the // desired bit length this.ShiftRight(FastInteger.FromBig(bigintDiff)); } this.VerifyKnownLength(); } }
private void ShiftBigToBits(int bits) { // Shifts a number until it reaches the given number of bits, // gathering information on whether the last bit discarded is set and // whether the discarded bits to the right of that bit are set. Assumes // that the big integer being shifted is positive. if (this.knownBitLength != null) { if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } // Shift by the difference in bit length if (this.knownBitLength.CompareToInt(bits) > 0) { var bs = 0; if (this.knownBitLength.CanFitInInt32()) { bs = this.knownBitLength.AsInt32(); bs -= bits; } else { FastInteger bitShift = this.knownBitLength.Copy().SubtractInt(bits); if (!bitShift.CanFitInInt32()) { this.ShiftRight(bitShift); return; } bs = bitShift.AsInt32(); } this.knownBitLength.SetInt(bits); this.discardedBitCount.AddInt(bs); if (bs == 1) { bool odd = !this.shiftedBigInt.IsEven; this.shiftedBigInt >>= 1; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = odd ? 1 : 0; } else { this.bitsAfterLeftmost |= this.bitLeftmost; EInteger lowestSetBit = this.shiftedBigInt.GetLowBitAsEInteger(); if (lowestSetBit.CompareTo(bs - 1) < 0) { // One of the discarded bits after // the last one is set this.bitsAfterLeftmost |= 1; this.bitLeftmost = this.shiftedBigInt.GetSignedBit(bs - 1) ? 1 : 0; } else if (lowestSetBit.CompareTo(bs - 1) > 0) { // Means all discarded bits are zero this.bitLeftmost = 0; } else { // Only the last discarded bit is set this.bitLeftmost = 1; } this.shiftedBigInt >>= bs; } if (bits < SmallBitLength) { // Shifting to small number of bits, // convert to small integer this.isSmall = true; this.shiftedSmall = (int)this.shiftedBigInt; } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; } }
private void ShiftRightBig(int bits) { if (bits <= 0) { return; } if (this.shiftedBigInt.IsZero) { this.discardedBitCount.AddInt(bits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.isSmall = true; this.shiftedSmall = 0; this.knownBitLength = new FastInteger(1); return; } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); this.discardedBitCount.AddInt(bits); int cmp = this.knownBitLength.CompareToInt(bits); if (cmp < 0) { // too few bits this.bitsAfterLeftmost |= this.bitLeftmost; this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.bitLeftmost = 0; this.isSmall = true; this.shiftedSmall = 0; this.knownBitLength = new FastInteger(1); } else { // enough bits in the current value int bs = bits; this.knownBitLength.SubtractInt(bits); if (bs == 1) { bool odd = !this.shiftedBigInt.IsEven; this.shiftedBigInt >>= 1; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = odd ? 1 : 0; } else { this.bitsAfterLeftmost |= this.bitLeftmost; EInteger lowestSetBit = this.shiftedBigInt.GetLowBitAsEInteger(); if (lowestSetBit.CompareTo(bs - 1) < 0) { // One of the discarded bits after // the last one is set this.bitsAfterLeftmost |= 1; this.bitLeftmost = this.shiftedBigInt.GetSignedBit(bs - 1) ? 1 : 0; } else if (lowestSetBit.CompareTo(bs - 1) > 0) { // Means all discarded bits are zero this.bitLeftmost = 0; } else { // Only the last discarded bit is set this.bitLeftmost = 1; } this.shiftedBigInt >>= bs; } if (this.knownBitLength.CompareToInt(SmallBitLength) < 0) { // Shifting to small number of bits, // convert to small integer this.isSmall = true; this.shiftedSmall = (int)this.shiftedBigInt; } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; } }
internal FastInteger Add(FastInteger val) { this.CheckFrozen(); EInteger valValue; switch (this.integerMode) { case 0: if (val.integerMode == 0) { if ((this.smallValue < 0 && (int)val.smallValue < Int32.MinValue - this.smallValue) || (this.smallValue > 0 && (int)val.smallValue > Int32.MaxValue - this.smallValue)) { // would overflow if (val.smallValue >= 0) { this.integerMode = 1; this.mnum = new MutableNumber(this.smallValue); this.mnum.Add(val.smallValue); } else { this.integerMode = 2; this.largeValue = (EInteger)this.smallValue; this.largeValue += (EInteger)val.smallValue; } } else { this.smallValue += val.smallValue; } } else { integerMode = 2; largeValue = (EInteger)smallValue; valValue = val.AsEInteger(); largeValue += (EInteger)valValue; } break; case 1: if (val.integerMode == 0 && val.smallValue >= 0) { this.mnum.Add(val.smallValue); } else { integerMode = 2; largeValue = mnum.ToEInteger(); valValue = val.AsEInteger(); largeValue += (EInteger)valValue; } break; case 2: valValue = val.AsEInteger(); this.largeValue += (EInteger)valValue; break; default: throw new InvalidOperationException(); } return(this); }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Subtract(PeterO.Numbers.FastInteger)"]/*'/> internal FastInteger Subtract(FastInteger val) { this.CheckFrozen(); EInteger valValue; switch (this.integerMode) { case 0: if (val.integerMode == 0) { int vsv = val.smallValue; if ((vsv < 0 && Int32.MaxValue + vsv < this.smallValue) || (vsv > 0 && Int32.MinValue + vsv > this.smallValue)) { // would overflow, convert to large this.integerMode = 2; this.largeValue = (EInteger)this.smallValue; this.largeValue -= (EInteger)vsv; } else { this.smallValue -= vsv; } } else { integerMode = 2; largeValue = (EInteger)smallValue; valValue = val.AsEInteger(); largeValue -= (EInteger)valValue; } break; case 1: if (val.integerMode == 1) { // NOTE: Mutable numbers are // currently always zero or positive this.mnum.Subtract(val.mnum); } else if (val.integerMode == 0 && val.smallValue >= 0) { mnum.SubtractInt(val.smallValue); } else { integerMode = 2; largeValue = mnum.ToEInteger(); valValue = val.AsEInteger(); largeValue -= (EInteger)valValue; } break; case 2: valValue = val.AsEInteger(); this.largeValue -= (EInteger)valValue; break; default: throw new InvalidOperationException(); } return(this); }
public void AddPower(EInteger input, EInteger output) { lock (this.outputs) { if (this.size < MaxSize) { // Shift newer entries down for (int i = this.size; i > 0; --i) { this.inputs[i] = this.inputs[i - 1]; this.inputsInts[i] = this.inputsInts[i - 1]; this.outputs[i] = this.outputs[i - 1]; } this.inputs[0] = input; this.inputsInts[0] = input.CanFitInInt32() ? input.ToInt32Checked() : -1; this.outputs[0] = output; ++this.size; } else { // Shift newer entries down for (int i = MaxSize - 1; i > 0; --i) { this.inputs[i] = this.inputs[i - 1]; this.inputsInts[i] = this.inputsInts[i - 1]; this.outputs[i] = this.outputs[i - 1]; } this.inputs[0] = input; this.inputsInts[0] = input.CanFitInInt32() ? input.ToInt32Checked() : -1; this.outputs[0] = output; } } }
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; 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; }
private static EInteger FromRadixSubstringGeneral( string cs, int radix, int index, int endIndex, bool negative, bool throwException) { if (endIndex - index > 72) { int midIndex = index + ((endIndex - index) / 2); EInteger eia = FromRadixSubstringGeneral( cs, radix, index, midIndex, false, throwException); // DebugUtility.Log("eia="+eia); EInteger eib = FromRadixSubstringGeneral( cs, radix, midIndex, endIndex, false, throwException); // DebugUtility.Log("eib="+eib); EInteger mult = null; int intpow = endIndex - midIndex; if (radix == 10) { eia = NumberUtility.MultiplyByPowerOfFive(eia, intpow).ShiftLeft(intpow); } else if (radix == 5) { eia = NumberUtility.MultiplyByPowerOfFive(eia, intpow); } else { mult = EInteger.FromInt32(radix).Pow(endIndex - midIndex); eia = eia.Multiply(mult); } eia = eia.Add(eib); // DebugUtility.Log("index={0} {1} {2} [pow={3}] [pow={4} ms, muladd={5} ms]", // index, midIndex, endIndex, endIndex-midIndex, swPow.ElapsedMilliseconds, // swMulAdd.ElapsedMilliseconds); if (negative) { eia = eia.Negate(); } // DebugUtility.Log("eia now="+eia); return(eia); } else { return(FromRadixSubstringInner( cs, radix, index, endIndex, negative, throwException)); } }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EContext.WithBigExponentRange(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/> public EContext WithBigExponentRange( EInteger exponentMin, EInteger exponentMax) { if (exponentMin == null) { throw new ArgumentNullException("exponentMin"); } if (exponentMax == null) { throw new ArgumentNullException("exponentMax"); } if (exponentMin.CompareTo(exponentMax) > 0) { throw new ArgumentException("exponentMin greater than exponentMax"); } EContext pc = this.Copy(); pc.hasExponentRange = true; pc.exponentMin = exponentMin; pc.exponentMax = exponentMax; return pc; }
private static EInteger FromRadixSubstringInner( string cs, int radix, int index, int endIndex, bool negative, bool throwException) { if (radix <= 10) { long rv = 0; var digitCount = 0; if (radix == 10) { for (int i = index; i < endIndex; ++i) { char c = cs[i]; var digit = (int)c - 0x30; if (digit >= radix || digit < 0) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } if (digitCount < 0 || digitCount >= 18) { digitCount = -1; break; } else if (digitCount > 0 || digit != 0) { ++digitCount; } rv = (rv * 10) + digit; } // DebugUtility.Log("short="+(negative ? -rv : rv)); if (digitCount >= 0) { return(EInteger.FromInt64(negative ? -rv : rv)); } } else { for (int i = index; i < endIndex; ++i) { char c = cs[i]; int digit = (c >= 0x80) ? 36 : ((int)c - 0x30); if (digit >= radix || digit < 0) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } if (digitCount < 0 || digitCount >= 18) { digitCount = -1; break; } else if (digitCount > 0 || digit != 0) { ++digitCount; } rv = (rv * radix) + digit; } if (digitCount >= 0) { return(EInteger.FromInt64(negative ? -rv : rv)); } } } int[] c2d = EInteger.CharToDigit; int[] d2w = EInteger.DigitsInWord; long lsize = ((long)(endIndex - index) * 100 / d2w[radix]) + 1; lsize = Math.Min(lsize, Int32.MaxValue); lsize = Math.Max(lsize, 5); var bigint = new short[(int)lsize]; if (radix == 10) { long rv = 0; int ei = endIndex - index <= 18 ? endIndex : index + 18; for (int i = index; i < ei; ++i) { char c = cs[i]; var digit = (int)c - 0x30; if (digit >= radix || digit < 0) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } rv = (rv * 10) + digit; } bigint[0] = unchecked ((short)(rv & ShortMask)); bigint[1] = unchecked ((short)((rv >> 16) & ShortMask)); bigint[2] = unchecked ((short)((rv >> 32) & ShortMask)); bigint[3] = unchecked ((short)((rv >> 48) & ShortMask)); int bn = Math.Min(bigint.Length, 5); for (int i = ei; i < endIndex; ++i) { short carry = 0; var digit = 0; var overf = 0; if (i < endIndex - 3) { overf = 55536; // 2**16 minus 10**4 var d1 = (int)cs[i] - 0x30; var d2 = (int)cs[i + 1] - 0x30; var d3 = (int)cs[i + 2] - 0x30; var d4 = (int)cs[i + 3] - 0x30; i += 3; if (d1 >= 10 || d1 < 0 || d2 >= 10 || d2 < 0 || d3 >= 10 || d3 < 0 || d4 >= 10 || d4 < 0) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } digit = (d1 * 1000) + (d2 * 100) + (d3 * 10) + d4; // Multiply by 10**4 for (int j = 0; j < bn; ++j) { int p; p = unchecked ((((int)bigint[j]) & ShortMask) * 10000); int p2 = ((int)carry) & ShortMask; p = unchecked (p + p2); bigint[j] = unchecked ((short)p); carry = unchecked ((short)(p >> 16)); } } else { overf = 65526; // 2**16 minus radix 10 char c = cs[i]; digit = (int)c - 0x30; if (digit >= 10 || digit < 0) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } // Multiply by 10 for (int j = 0; j < bn; ++j) { int p; p = unchecked ((((int)bigint[j]) & ShortMask) * 10); int p2 = ((int)carry) & ShortMask; p = unchecked (p + p2); bigint[j] = unchecked ((short)p); carry = unchecked ((short)(p >> 16)); } } if (carry != 0) { bigint = EInteger.GrowForCarry(bigint, carry); } // Add the parsed digit if (digit != 0) { int d = bigint[0] & ShortMask; if (d <= overf) { bigint[0] = unchecked ((short)(d + digit)); } else if (EInteger.IncrementWords( bigint, 0, bigint.Length, (short)digit) != 0) { bigint = EInteger.GrowForCarry(bigint, (short)1); } } bn = Math.Min(bigint.Length, bn + 1); } } else { var haveSmallInt = true; int[] msi = EInteger.MaxSafeInts; int maxSafeInt = msi[radix - 2]; int maxShortPlusOneMinusRadix = 65536 - radix; var smallInt = 0; for (int i = index; i < endIndex; ++i) { char c = cs[i]; int digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= radix) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } if (haveSmallInt && smallInt < maxSafeInt) { smallInt = (smallInt * radix) + digit; } else { if (haveSmallInt) { bigint[0] = unchecked ((short)(smallInt & ShortMask)); bigint[1] = unchecked ((short)((smallInt >> 16) & ShortMask)); haveSmallInt = false; } // Multiply by the radix short carry = 0; int n = bigint.Length; for (int j = 0; j < n; ++j) { int p; p = unchecked ((((int)bigint[j]) & ShortMask) * radix); int p2 = ((int)carry) & ShortMask; p = unchecked (p + p2); bigint[j] = unchecked ((short)p); carry = unchecked ((short)(p >> 16)); } if (carry != 0) { bigint = EInteger.GrowForCarry(bigint, carry); } // Add the parsed digit if (digit != 0) { int d = bigint[0] & ShortMask; if (d <= maxShortPlusOneMinusRadix) { bigint[0] = unchecked ((short)(d + digit)); } else if (EInteger.IncrementWords( bigint, 0, bigint.Length, (short)digit) != 0) { bigint = EInteger.GrowForCarry(bigint, (short)1); } } } } if (haveSmallInt) { bigint[0] = unchecked ((short)(smallInt & ShortMask)); bigint[1] = unchecked ((short)((smallInt >> 16) & ShortMask)); } } int count = EInteger.CountWords(bigint); return((count == 0) ? EInteger.Zero : new EInteger( count, bigint, negative)); }
public static void DoTestShiftRight2(string m1, int m2, EInteger result) { EInteger bigintA = BigFromString(m1); TestCommon.CompareTestEqualAndConsistent(result, bigintA >> m2); m2 = -m2; TestCommon.CompareTestEqualAndConsistent(result, bigintA << m2); }
public static EInteger FromRadixSubstringImpl( string cs, int radix, int index, int endIndex, bool throwException) { if (radix < 2) { if (!throwException) { return(null); } else { throw new ArgumentException("radix(" + radix + ") is less than 2"); } } if (radix > 36) { if (!throwException) { return(null); } else { throw new ArgumentException("radix(" + radix + ") is more than 36"); } } if (index < 0) { if (!throwException) { return(null); } else { throw new ArgumentException("index(" + index + ") is less than " + "0"); } } if (index > cs.Length) { if (!throwException) { return(null); } else { throw new ArgumentException("index(" + index + ") is more than " + cs.Length); } } if (endIndex < 0) { if (!throwException) { return(null); } else { throw new ArgumentException("endIndex(" + endIndex + ") is less than 0"); } } if (endIndex > cs.Length) { if (!throwException) { return(null); } else { throw new ArgumentException("endIndex(" + endIndex + ") is more than " + cs.Length); } } if (endIndex < index) { if (!throwException) { return(null); } else { throw new ArgumentException("endIndex(" + endIndex + ") is less than " + index); } } if (index == endIndex) { if (!throwException) { return(null); } else { throw new FormatException("No digits"); } } var negative = false; if (cs[index] == '-') { ++index; if (index == endIndex) { if (!throwException) { return(null); } else { throw new FormatException("No digits"); } } negative = true; } // Skip leading zeros for (; index < endIndex; ++index) { char c = cs[index]; if (c != 0x30) { break; } } int effectiveLength = endIndex - index; if (effectiveLength == 0) { return(EInteger.Zero); } int[] c2d = EInteger.CharToDigit; short[] bigint; if (radix == 16) { // Special case for hexadecimal radix int leftover = effectiveLength & 3; int wordCount = effectiveLength >> 2; if (leftover != 0) { ++wordCount; } bigint = new short[wordCount]; int currentDigit = wordCount - 1; // Get most significant digits if effective // length is not divisible by 4 if (leftover != 0) { var extraWord = 0; for (int i = 0; i < leftover; ++i) { extraWord <<= 4; char c = cs[index + i]; int digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= 16) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } extraWord |= digit; } bigint[currentDigit] = unchecked ((short)extraWord); --currentDigit; index += leftover; } #if DEBUG if ((endIndex - index) % 4 != 0) { if (!throwException) { return(null); } else { throw new InvalidOperationException("doesn't satisfy (endIndex - index) %" + "\u00204 == 0"); } } #endif while (index < endIndex) { char c = cs[index + 3]; int digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= 16) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } int word = digit; c = cs[index + 2]; digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= 16) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } word |= digit << 4; c = cs[index + 1]; digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= 16) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } word |= digit << 8; c = cs[index]; digit = (c >= 0x80) ? 36 : c2d[(int)c]; if (digit >= 16) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } word |= digit << 12; index += 4; bigint[currentDigit] = unchecked ((short)word); --currentDigit; } int count = EInteger.CountWords(bigint); return((count == 0) ? EInteger.Zero : new EInteger( count, bigint, negative)); } else if (radix == 2) { // Special case for binary radix int leftover = effectiveLength & 15; int wordCount = effectiveLength >> 4; if (leftover != 0) { ++wordCount; } bigint = new short[wordCount]; int currentDigit = wordCount - 1; // Get most significant digits if effective // length is not divisible by 4 if (leftover != 0) { var extraWord = 0; for (int i = 0; i < leftover; ++i) { extraWord <<= 1; char c = cs[index + i]; int digit = (c == '0') ? 0 : ((c == '1') ? 1 : 2); if (digit >= 2) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } extraWord |= digit; } bigint[currentDigit] = unchecked ((short)extraWord); --currentDigit; index += leftover; } while (index < endIndex) { var word = 0; int idx = index + 15; for (var i = 0; i < 16; ++i) { char c = cs[idx]; int digit = (c == '0') ? 0 : ((c == '1') ? 1 : 2); if (digit >= 2) { if (!throwException) { return(null); } else { throw new FormatException("Illegal character found"); } } --idx; word |= digit << i; } index += 16; bigint[currentDigit] = unchecked ((short)word); --currentDigit; } int count = EInteger.CountWords(bigint); return((count == 0) ? EInteger.Zero : new EInteger( count, bigint, negative)); } else { return(FromRadixSubstringGeneral( cs, radix, index, endIndex, negative, throwException)); } }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Multiply(System.Int32)"]/*'/> internal FastInteger Multiply(int val) { this.CheckFrozen(); if (val == 0) { this.smallValue = 0; this.integerMode = 0; } else { switch (this.integerMode) { case 0: { long amult = ((long)val) * ((long)this.smallValue); if (amult > Int32.MaxValue || amult < Int32.MinValue) { // would overflow, convert to large bool apos = this.smallValue > 0L; bool bpos = val > 0L; if (apos && bpos) { // if both operands are nonnegative // convert to mutable big integer this.integerMode = 1; this.mnum = MutableNumber.FromLong(amult); } else { // if either operand is negative // convert to big integer this.integerMode = 2; this.largeValue = EInteger.FromInt64(amult); } } else { this.smallValue = unchecked ((int)amult); } break; } case 1: if (val < 0) { this.integerMode = 2; this.largeValue = this.mnum.ToEInteger(); this.largeValue *= (EInteger)val; } else { mnum.Multiply(val); } break; case 2: this.largeValue *= (EInteger)val; break; default: throw new InvalidOperationException(); } } return(this); }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.Equals(PeterO.Numbers.EInteger)"]/*'/> public bool Equals(EInteger other) { return((other != null) && (this.CompareTo(other) == 0)); }
public CBORObject GetString(EInteger bigIndex) { if (bigIndex.Sign < 0) { throw new CBORException("Unexpected index"); } if (!bigIndex.CanFitInInt32()) { throw new CBORException("Index " + bigIndex + " is bigger than supported "); } var index = (int)bigIndex; List<CBORObject> lastList = this.stack[this.stack.Count - 1]; if (index >= lastList.Count) { throw new CBORException("Index " + index + " is not valid"); } CBORObject ret = lastList[index]; // Byte strings are mutable, so make a copy return (ret.Type == CBORType.ByteString) ? CBORObject.FromObject(ret.GetByteString()) : ret; }
internal static FastIntegerFixed FromBig(EInteger bigintVal) { return(bigintVal.CanFitInInt32() ? FromInt32(bigintVal.ToInt32Unchecked()) : new FastIntegerFixed(IntegerMode.LargeValue, 0, bigintVal)); }
internal static EInteger ShiftLeft(EInteger val, EInteger bigShift) { #if DEBUG if (val == null) { throw new ArgumentNullException("val"); } if (bigShift == null) { throw new ArgumentNullException("bigShift"); } #endif if (val.IsZero) { return val; } while (bigShift.CompareTo(ValueBigShiftIteration) > 0) { val <<= 1000000; bigShift -= (EInteger)ValueBigShiftIteration; } var lastshift = (int)bigShift; val <<= lastshift; return val; }
internal static EFloat DoubleEFloatFromString( char[] chars, int offset, int length, EContext ctx, bool throwException) { int tmpoffset = offset; if (chars == null) { if (!throwException) { return(null); } else { throw new ArgumentNullException(nameof(chars)); } } if (length == 0) { if (!throwException) { return(null); } else { throw new FormatException(); } } int endStr = tmpoffset + length; var negative = false; var haveDecimalPoint = false; var haveDigits = false; var haveExponent = false; var newScaleInt = 0; var digitStart = 0; int i = tmpoffset; long mantissaLong = 0L; // Ordinary number if (chars[i] == '+' || chars[i] == '-') { if (chars[i] == '-') { negative = true; } ++i; } digitStart = i; int digitEnd = i; int decimalDigitStart = i; var haveNonzeroDigit = false; var decimalPrec = 0; int decimalDigitEnd = i; var nonzeroBeyondMax = false; var lastdigit = -1; // 768 is maximum precision of a decimal // half-ULP in double format var maxDecimalPrec = 768; if (length > 21) { int eminInt = ctx.EMin.ToInt32Checked(); int emaxInt = ctx.EMax.ToInt32Checked(); int precInt = ctx.Precision.ToInt32Checked(); if (eminInt >= -14 && emaxInt <= 15) { maxDecimalPrec = (precInt <= 11) ? 21 : 63; } else if (eminInt >= -126 && emaxInt <= 127) { maxDecimalPrec = (precInt <= 24) ? 113 : 142; } } for (; i < endStr; ++i) { char ch = chars[i]; if (ch >= '0' && ch <= '9') { var thisdigit = (int)(ch - '0'); haveDigits = true; haveNonzeroDigit |= thisdigit != 0; if (decimalPrec > maxDecimalPrec) { if (thisdigit != 0) { nonzeroBeyondMax = true; } if (!haveDecimalPoint) { // NOTE: Absolute value will not be more than // the char[] portion's length, so will fit comfortably // in an 'int'. newScaleInt = checked (newScaleInt + 1); } continue; } lastdigit = thisdigit; if (haveNonzeroDigit) { ++decimalPrec; } if (haveDecimalPoint) { decimalDigitEnd = i + 1; } else { digitEnd = i + 1; } if (mantissaLong <= 922337203685477580L) { mantissaLong *= 10; mantissaLong += thisdigit; } else { mantissaLong = Int64.MaxValue; } if (haveDecimalPoint) { // NOTE: Absolute value will not be more than // the portion's length, so will fit comfortably // in an 'int'. newScaleInt = checked (newScaleInt - 1); } } else if (ch == '.') { if (haveDecimalPoint) { if (!throwException) { return(null); } else { throw new FormatException(); } } haveDecimalPoint = true; decimalDigitStart = i + 1; decimalDigitEnd = i + 1; } else if (ch == 'E' || ch == 'e') { haveExponent = true; ++i; break; } else { if (!throwException) { return(null); } else { throw new FormatException(); } } } if (!haveDigits) { if (!throwException) { return(null); } else { throw new FormatException(); } } var expInt = 0; var expoffset = 1; var expDigitStart = -1; var expPrec = 0; bool zeroMantissa = !haveNonzeroDigit; haveNonzeroDigit = false; EFloat ef1, ef2; if (haveExponent) { haveDigits = false; if (i == endStr) { if (!throwException) { return(null); } else { throw new FormatException(); } } char ch = chars[i]; if (ch == '+' || ch == '-') { if (ch == '-') { expoffset = -1; } ++i; } expDigitStart = i; for (; i < endStr; ++i) { ch = chars[i]; if (ch >= '0' && ch <= '9') { haveDigits = true; var thisdigit = (int)(ch - '0'); haveNonzeroDigit |= thisdigit != 0; if (haveNonzeroDigit) { ++expPrec; } if (expInt <= 214748364) { expInt *= 10; expInt += thisdigit; } else { expInt = Int32.MaxValue; } } else { if (!throwException) { return(null); } else { throw new FormatException(); } } } if (!haveDigits) { if (!throwException) { return(null); } else { throw new FormatException(); } } expInt *= expoffset; if (expPrec > 12) { // Exponent that can't be compensated by digit // length without remaining beyond Int32 range if (expoffset < 0) { return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa)); } else { return(EFloat.SignalOverflow(ctx, negative, zeroMantissa)); } } } if (i != endStr) { if (!throwException) { return(null); } else { throw new FormatException(); } } if (expInt != Int32.MaxValue && expInt > -Int32.MaxValue && mantissaLong != Int64.MaxValue && (ctx == null || !ctx.HasFlagsOrTraps)) { if (mantissaLong == 0) { EFloat ef = EFloat.Create( EInteger.Zero, EInteger.FromInt32(expInt)); if (negative) { ef = ef.Negate(); } return(ef.RoundToPrecision(ctx)); } var finalexp = (long)expInt + (long)newScaleInt; long ml = mantissaLong; if (finalexp >= -22 && finalexp <= 44) { var iexp = (int)finalexp; while (ml <= 900719925474099L && iexp > 22) { ml *= 10; --iexp; } int iabsexp = Math.Abs(iexp); if (ml < 9007199254740992L && iabsexp == 0) { return(EFloat.FromInt64(negative ? -mantissaLong : mantissaLong).RoundToPrecision(ctx)); } else if (ml < 9007199254740992L && iabsexp <= 22) { EFloat efn = EFloat.FromEInteger(NumberUtility.FindPowerOfTen(iabsexp)); if (negative) { ml = -ml; } EFloat efml = EFloat.FromInt64(ml); if (iexp < 0) { return(efml.Divide(efn, ctx)); } else { return(efml.Multiply(efn, ctx)); } } } long adjexpUpperBound = finalexp + (decimalPrec - 1); long adjexpLowerBound = finalexp; if (adjexpUpperBound < -326) { return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa)); } else if (adjexpLowerBound > 309) { return(EFloat.SignalOverflow(ctx, negative, zeroMantissa)); } if (negative) { mantissaLong = -mantissaLong; } long absfinalexp = Math.Abs(finalexp); ef1 = EFloat.Create(mantissaLong, (int)0); ef2 = EFloat.FromEInteger(NumberUtility.FindPowerOfTen(absfinalexp)); if (finalexp < 0) { EFloat efret = ef1.Divide(ef2, ctx); /* Console.WriteLine("div " + ef1 + "/" + ef2 + " -> " + (efret)); */return(efret); } else { return(ef1.Multiply(ef2, ctx)); } } EInteger mant = null; EInteger exp = (!haveExponent) ? EInteger.Zero : EInteger.FromSubstring(chars, expDigitStart, endStr); if (expoffset < 0) { exp = exp.Negate(); } exp = exp.Add(newScaleInt); if (nonzeroBeyondMax) { exp = exp.Subtract(1); ++decimalPrec; } EInteger adjExpUpperBound = exp.Add(decimalPrec).Subtract(1); EInteger adjExpLowerBound = exp; // DebugUtility.Log("exp=" + adjExpLowerBound + "~" + (adjExpUpperBound)); if (adjExpUpperBound.CompareTo(-326) < 0) { return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa)); } else if (adjExpLowerBound.CompareTo(309) > 0) { return(EFloat.SignalOverflow(ctx, negative, zeroMantissa)); } if (zeroMantissa) { EFloat ef = EFloat.Create( EInteger.Zero, exp); if (negative) { ef = ef.Negate(); } return(ef.RoundToPrecision(ctx)); } else if (decimalDigitStart != decimalDigitEnd) { if (digitEnd - digitStart == 1 && chars[digitStart] == '0') { mant = EInteger.FromSubstring( chars, decimalDigitStart, decimalDigitEnd); } else { char[] ctmpstr = Extras.CharsConcat( chars, digitStart, digitEnd - digitStart, chars, decimalDigitStart, decimalDigitEnd - decimalDigitStart); mant = EInteger.FromString(ctmpstr); } } else { mant = EInteger.FromSubstring(chars, digitStart, digitEnd); } if (nonzeroBeyondMax) { mant = mant.Multiply(10).Add(1); } if (negative) { mant = mant.Negate(); } return(EDecimal.Create(mant, exp).ToEFloat(ctx)); }
public EInteger[] FindCachedPowerOrSmaller(EInteger bi) { EInteger[] ret = null; EInteger minValue = null; if (bi.CanFitInInt32()) { return this.FindCachedPowerIntOrSmaller(bi.ToInt32Checked()); } lock (this.outputs) { for (var i = 0; i < this.size; ++i) { if (this.inputs[i].CompareTo(bi) <= 0 && (minValue == null || this.inputs[i].CompareTo(minValue) >= 0)) { // DebugUtility.Log("Have cached power (" + inputs[i] + "," + bi + ") "); ret = new EInteger[2]; ret[0] = this.inputs[i]; ret[1] = this.outputs[i]; minValue = this.inputs[i]; } } } return ret; }
private T RoundBeforeOp(T val, EContext ctx) { if (ctx == null || !ctx.HasMaxPrecision) { return(val); } int thisFlags = this.GetHelper().GetFlags(val); if ((thisFlags & BigNumberFlags.FlagSpecial) != 0) { return(val); } FastInteger fastPrecision = FastInteger.FromBig(ctx.Precision); EInteger mant = this.GetHelper().GetMantissa(val).Abs(); FastInteger digits = this.GetHelper().CreateShiftAccumulator(mant).GetDigitLength(); EContext ctx2 = ctx.WithBlankFlags().WithTraps(0); if (digits.CompareTo(fastPrecision) <= 0) { // Rounding is only to be done if the digit count is // too big (distinguishing this case is material // if the value also has an exponent that's out of range) return(val); } val = this.wrapper.RoundToPrecision(val, ctx2); // the only time rounding can signal an invalid // operation is if an operand is signaling NaN, but // this was already checked beforehand #if DEBUG if ((ctx2.Flags & EContext.FlagInvalid) != 0) { throw new ArgumentException("doesn't satisfy (ctx2.Flags&FlagInvalid)==0"); } #endif if ((ctx2.Flags & EContext.FlagInexact) != 0) { if (ctx.HasFlags) { ctx.Flags |= BigNumberFlags.LostDigitsFlags; } } if ((ctx2.Flags & EContext.FlagRounded) != 0) { if (ctx.HasFlags) { ctx.Flags |= EContext.FlagRounded; } } if ((ctx2.Flags & EContext.FlagSubnormal) != 0) { // Console.WriteLine("Subnormal input: " + val); } if ((ctx2.Flags & EContext.FlagUnderflow) != 0) { // Console.WriteLine("Underflow"); } if ((ctx2.Flags & EContext.FlagOverflow) != 0) { bool neg = (thisFlags & BigNumberFlags.FlagNegative) != 0; ctx.Flags |= EContext.FlagLostDigits; return(this.SignalOverflow2(ctx, neg)); } return(val); }
public EInteger GetCachedPower(EInteger bi) { if (bi.CanFitInInt32()) { return this.GetCachedPowerInt(bi.ToInt32Checked()); } lock (this.outputs) { for (var i = 0; i < this.size; ++i) { if (bi.Equals(this.inputs[i])) { if (i != 0) { EInteger tmp; // Move to head of cache if it isn't already tmp = this.inputs[i]; this.inputs[i] = this.inputs[0]; this.inputs[0] = tmp; int tmpi = this.inputsInts[i]; this.inputsInts[i] = this.inputsInts[0]; this.inputsInts[0] = tmpi; tmp = this.outputs[i]; this.outputs[i] = this.outputs[0]; this.outputs[0] = tmp; // Move formerly newest to next newest if (i != 1) { tmp = this.inputs[i]; this.inputs[i] = this.inputs[1]; this.inputs[1] = tmp; tmpi = this.inputsInts[i]; this.inputsInts[i] = this.inputsInts[1]; this.inputsInts[1] = tmpi; tmp = this.outputs[i]; this.outputs[i] = this.outputs[1]; this.outputs[1] = tmp; } } return this.outputs[0]; } } } return null; }
private T PostProcessEx( T thisValue, EContext ctxDest, EContext ctxSrc, bool afterDivision, bool afterQuantize) { int thisFlags = this.GetHelper().GetFlags(thisValue); if (ctxDest != null && ctxSrc != null) { if (ctxDest.HasFlags) { if (!ctxSrc.ClampNormalExponents) { ctxSrc.Flags &= ~EContext.FlagClamped; } ctxDest.Flags |= ctxSrc.Flags; if ((ctxSrc.Flags & EContext.FlagSubnormal) != 0) { // Treat subnormal numbers as underflows ctxDest.Flags |= BigNumberFlags.UnderflowFlags; } } } if ((thisFlags & BigNumberFlags.FlagSpecial) != 0) { return((ctxDest.Flags == 0) ? this.SignalInvalid(ctxDest) : thisValue); } EInteger mant = this.GetHelper().GetMantissa(thisValue).Abs(); if (mant.IsZero) { return(afterQuantize ? this.GetHelper().CreateNewWithFlags( mant, this.GetHelper().GetExponent(thisValue), 0) : this.wrapper.RoundToPrecision( this.GetHelper().ValueOf(0), ctxDest)); } if (afterQuantize) { return(thisValue); } EInteger exp = this.GetHelper().GetExponent(thisValue); if (exp.Sign > 0) { FastInteger fastExp = FastInteger.FromBig(exp); if (ctxDest == null || !ctxDest.HasMaxPrecision) { mant = this.GetHelper().MultiplyByRadixPower(mant, fastExp); return(this.GetHelper().CreateNewWithFlags( mant, EInteger.Zero, thisFlags)); } if (!ctxDest.ExponentWithinRange(exp)) { return(thisValue); } FastInteger prec = FastInteger.FromBig(ctxDest.Precision); FastInteger digits = this.GetHelper().CreateShiftAccumulator(mant).GetDigitLength(); prec.Subtract(digits); if (prec.Sign > 0 && prec.CompareTo(fastExp) >= 0) { mant = this.GetHelper().MultiplyByRadixPower(mant, fastExp); return(this.GetHelper().CreateNewWithFlags( mant, EInteger.Zero, thisFlags)); } if (afterDivision) { int radix = this.GetHelper().GetRadix(); mant = NumberUtility.ReduceTrailingZeros( mant, fastExp, radix, null, null, null); thisValue = this.GetHelper().CreateNewWithFlags( mant, fastExp.AsEInteger(), thisFlags); } } else if (afterDivision && exp.Sign < 0) { FastInteger fastExp = FastInteger.FromBig(exp); int radix = this.GetHelper().GetRadix(); mant = NumberUtility.ReduceTrailingZeros( mant, fastExp, radix, null, null, new FastInteger(0)); thisValue = this.GetHelper().CreateNewWithFlags( mant, fastExp.AsEInteger(), thisFlags); } return(thisValue); }
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; }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.Xor(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/> public static EInteger Xor(EInteger a, EInteger b) { if (a == null) { throw new ArgumentNullException("a"); } if (b == null) { throw new ArgumentNullException("b"); } if (a == b) { return EInteger.Zero; } if (a.wordCount == 0) { return b; } if (b.wordCount == 0) { return a; } var valueXaNegative = false; int valueXaWordCount = 0; var valueXaReg = new short[a.wordCount]; Array.Copy(a.words, valueXaReg, valueXaReg.Length); var valueXbNegative = false; var valueXbReg = new short[b.wordCount]; Array.Copy(b.words, valueXbReg, valueXbReg.Length); valueXaNegative = a.negative; valueXaWordCount = a.wordCount; valueXbNegative = b.negative; valueXaReg = CleanGrow( valueXaReg, Math.Max(valueXaReg.Length, valueXbReg.Length)); valueXbReg = CleanGrow( valueXbReg, Math.Max(valueXaReg.Length, valueXbReg.Length)); if (valueXaNegative) { TwosComplement(valueXaReg, 0, (int)valueXaReg.Length); } if (valueXbNegative) { TwosComplement(valueXbReg, 0, (int)valueXbReg.Length); } valueXaNegative ^= valueXbNegative; XorWords(valueXaReg, valueXaReg, valueXbReg, (int)valueXaReg.Length); if (valueXaNegative) { TwosComplement(valueXaReg, 0, (int)valueXaReg.Length); } valueXaWordCount = CountWords(valueXaReg); return (valueXaWordCount == 0) ? EInteger.Zero : (new EInteger(valueXaWordCount, valueXaReg, valueXaNegative)); }
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; }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.ModPow(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/> public static EInteger ModPow( EInteger bigintValue, EInteger pow, EInteger mod) { if (bigintValue == null) { throw new ArgumentNullException("bigintValue"); } return bigintValue.ModPow(pow, mod); }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EContext.ExponentWithinRange(PeterO.Numbers.EInteger)"]/*'/> public bool ExponentWithinRange(EInteger exponent) { if (exponent == null) { throw new ArgumentNullException("exponent"); } if (!this.HasExponentRange) { return true; } if (this.bigintPrecision.IsZero) { // Only check EMax, since with an unlimited // precision, any exponent less than EMin will exceed EMin if // the mantissa is the right size return exponent.CompareTo(this.EMax) <= 0; } else { EInteger bigint = exponent; if (this.adjustExponent) { bigint += (EInteger)this.bigintPrecision; bigint -= EInteger.One; } return (bigint.CompareTo(this.EMin) >= 0) && (exponent.CompareTo(this.EMax) <= 0); } }
private void ShiftRightBig(int digits, bool truncate) { if (digits <= 0) { return; } if (this.shiftedBigInt.IsZero) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); return; } if (truncate) { EInteger bigquo; if (digits > 50) { // To avoid having to calculate a very big power of 10, // check the digit count to see if doing so can be avoided int bitLength = this.shiftedBigInt.GetUnsignedBitLength(); var bigPower = false; // 10^48 has 160 bits; 10^98 has 326; bit length is cheaper // to calculate than base-10 digit length if (bitLength < 160 || (digits > 100 && bitLength < 326)) { bigPower = true; } else { FastInteger knownDigits = this.GetDigitLength(); bigPower = knownDigits.Copy().SubtractInt(digits) .CompareToInt(-2) < 0; if (!bigPower) { // DebugUtility.Log("digitlength {0} [todiscard: {1}]" // , knownDigits, digits); } } if (bigPower) { // Power of 10 to be divided would be much bigger this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); this.isSmall = true; this.shiftedSmall = 0; return; } } if (this.shiftedBigInt.IsEven && this.bitLeftmost == 0) { EInteger[] quorem = this.shiftedBigInt.DivRem( NumberUtility.FindPowerOfTen(digits)); bigquo = quorem[0]; this.bitLeftmost |= quorem[1].IsZero ? 0 : 1; } else { this.bitLeftmost = 1; bigquo = this.shiftedBigInt.Divide( NumberUtility.FindPowerOfTen(digits)); } this.bitsAfterLeftmost |= this.bitLeftmost; this.discardedBitCount = this.discardedBitCount == null ? new FastInteger(digits) : this.discardedBitCount.AddInt(digits); if (bigquo.IsZero) { // Shifted all the way to 0 this.isSmall = true; this.shiftedBigInt = null; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); } else if (bigquo.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = bigquo.ToInt32Unchecked(); this.shiftedBigInt = null; this.UpdateKnownLengthInt(digits); } else { this.isSmall = false; this.shiftedBigInt = bigquo; this.UpdateKnownLengthInt(digits); } return; } if (digits == 1) { EInteger bigrem; EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem((EInteger)10); 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.AddInt(digits); this.UpdateKnownLengthInt(digits); return; } if (digits >= 2 && digits <= 8) { EInteger bigrem; EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem(NumberUtility.FindPowerOfTen(digits)); bigquo = divrem[0]; bigrem = divrem[1]; var intRem = (int)bigrem; int smallPower = ValueTenPowers[digits - 1]; int leftBit = intRem / smallPower; int otherBits = intRem - (leftBit * smallPower); this.bitsAfterLeftmost |= otherBits | this.bitLeftmost; this.bitLeftmost = leftBit; this.shiftedBigInt = bigquo; this.discardedBitCount = (this.discardedBitCount != null) ? this.discardedBitCount.AddInt(digits) : (new FastInteger(digits)); this.UpdateKnownLengthInt(digits); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; if (this.shiftedBigInt.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = this.shiftedBigInt.ToInt32Unchecked(); this.shiftedBigInt = null; } return; } this.knownDigitLength = this.knownDigitLength ?? this.CalcKnownDigitLength(); if (new FastInteger(digits).Decrement().CompareTo(this.knownDigitLength) >= 0) { // Shifting more bits than available this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; return; } if (this.shiftedBigInt.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = (int)this.shiftedBigInt; this.ShiftRightSmall(digits); return; } if (this.shiftedBigInt.CanFitInInt64()) { this.ShiftRightLong(this.shiftedBigInt.ToInt64Unchecked(), digits); return; } string str = this.shiftedBigInt.ToString(); // NOTE: Will be 1 if the value is 0 int digitLength = str.Length; var bitDiff = 0; if (digits > digitLength) { bitDiff = digits - digitLength; } this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; int digitShift = Math.Min(digitLength, digits); if (digits >= digitLength) { this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); } else { var newLength = (int)(digitLength - digitShift); if (newLength <= 9) { // Fits in a small number this.isSmall = true; this.shiftedSmall = FastParseLong(str, 0, newLength); } else { this.shiftedBigInt = EInteger.FromSubstring(str, 0, newLength); } this.UpdateKnownLengthInt(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; } } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; if (bitDiff > 0) { // Shifted more digits than the digit length this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; } }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.EContext.WithBigPrecision(PeterO.Numbers.EInteger)"]/*'/> public EContext WithBigPrecision(EInteger bigintPrecision) { if (bigintPrecision == null) { throw new ArgumentNullException("bigintPrecision"); } if (bigintPrecision.Sign < 0) { throw new ArgumentException("bigintPrecision's sign (" + bigintPrecision.Sign + ") is less than 0"); } EContext pc = this.Copy(); pc.bigintPrecision = bigintPrecision; return pc; }
private void ShiftRightLong(long shiftedLong, int digits) { if (digits <= 0) { return; } if (shiftedLong == 0) { this.shiftedSmall = 0; this.isSmall = true; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 2 && digits <= 8) { if (shiftedLong >= ValueTenPowers[digits]) { long bigPower = ValueTenPowers[digits]; long smallPower = ValueTenPowers[digits - 1]; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); long div = shiftedLong / bigPower; long rem = shiftedLong - (div * bigPower); long rem2 = rem / smallPower; this.bitLeftmost = (int)rem2; this.bitsAfterLeftmost |= ((rem - (rem2 * smallPower)) == 0) ? 0 : 1; this.isSmall = div <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)div; this.knownDigitLength = (div < 10) ? (new FastInteger(1)) : new FastInteger(LongDigitLength(div)); } else { this.shiftedBigInt = EInteger.FromInt64(div); this.knownDigitLength = (div < 10) ? (new FastInteger(1)) : this.CalcKnownDigitLength(); } return; } else if (this.shiftedSmall >= ValueTenPowers[digits - 1]) { int smallPower = ValueTenPowers[digits - 1]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } long rem = shiftedLong; long rem2 = rem / smallPower; this.bitLeftmost = (int)rem2; this.bitsAfterLeftmost |= ((rem - (rem2 * smallPower)) == 0) ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitLeftmost = 0; this.bitsAfterLeftmost |= (shiftedLong == 0) ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } } this.knownDigitLength = new FastInteger( LongDigitLength(shiftedLong)); if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } var digitsShifted = 0; while (digits > 0) { if (shiftedLong == 0) { this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; break; } else { long newShift = (shiftedLong < 43698) ? ((shiftedLong * 26215) >> 18) : (shiftedLong / 10); var digit = (int)(shiftedLong - (newShift * 10)); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = digit; --digits; ++digitsShifted; shiftedLong = newShift; } } this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digitsShifted); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; }
private static EInteger FuzzInteger( EInteger ei, int fuzzes, RandomGenerator r) { byte[] bytes = ei.ToBytes(true); int bits = ei.GetUnsignedBitLength(); for (var i = 0; i < fuzzes; ++i) { int bit = r.UniformInt(bits); bytes[bit / 8] ^= (byte)(1 << (bit & 0x07)); } return EInteger.FromBytes(bytes, true); }
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; } }
private static void TestGcdPair( EInteger biga, EInteger bigb, EInteger biggcd) { EInteger ba = biga.Gcd(bigb); EInteger bb = bigb.Gcd(biga); Assert.AreEqual(ba, biggcd); Assert.AreEqual(bb, biggcd); }
private void TruncateRightLong(long shiftedLong, int digits) { if (digits <= 0) { return; } if (shiftedLong == 0 || digits >= 21) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = shiftedLong == 0 ? 0 : 1; this.shiftedSmall = 0; this.isSmall = true; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 1 && digits <= TenPowersLong.Length - 1) { if (shiftedLong >= TenPowersLong[digits]) { long bigPower = TenPowersLong[digits]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } long quo = shiftedLong / bigPower; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (shiftedLong & 1) == 1 ? 1 : (shiftedLong - (quo * bigPower) == 0 ? 0 : 1); shiftedLong = quo; this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digits); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = shiftedLong == 0 ? 0 : 1; shiftedLong = 0; this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digits); return; } } this.ShiftRightInt(digits); }
public static void AssertAdd(EInteger bi, EInteger bi2, string s) { EIntegerTest.AssertBigIntegersEqual(s, bi + (EInteger)bi2); EIntegerTest.AssertBigIntegersEqual(s, bi2 + (EInteger)bi); EInteger negbi = EInteger.Zero - (EInteger)bi; EInteger negbi2 = EInteger.Zero - (EInteger)bi2; EIntegerTest.AssertBigIntegersEqual(s, bi - (EInteger)negbi2); EIntegerTest.AssertBigIntegersEqual(s, bi2 - (EInteger)negbi); }
internal static int[] GetLastWords(EInteger bigint, int numWords32Bit) { return (MutableNumber.FromEInteger(bigint).GetLastWordsInternal(numWords32Bit)); }