public void ShiftRight(FastInteger fastint) { if (fastint.Sign <= 0) { return; } if (fastint.CanFitInInt32()) { this.ShiftRightInt(fastint.AsInt32()); } else { EInteger bi = fastint.AsEInteger(); while (bi.Sign > 0) { var count = 1000000; if (bi.CompareTo((EInteger)1000000) < 0) { count = (int)bi; } this.ShiftRightInt(count); bi -= (EInteger)count; if (this.isSmall ? this.shiftedSmall == 0 : this.shiftedBigInt.IsZero) { break; } } } }
public static FastIntegerFixed FromFastInteger(FastInteger fi) { if (fi.CanFitInInt32()) { return(FromInt32(fi.AsInt32())); } else { return(FastIntegerFixed.FromBig(fi.AsEInteger())); } }
#pragma warning disable CS0618 // certain ERounding values are obsolete private T SignalOverflow2(EContext pc, bool neg) { if (pc != null) { ERounding roundingOnOverflow = pc.Rounding; if (pc.HasFlags) { pc.Flags |= EContext.FlagOverflow | EContext.FlagInexact | EContext.FlagRounded; } if (pc.HasMaxPrecision && pc.HasExponentRange && (roundingOnOverflow == ERounding.Down || roundingOnOverflow == ERounding.ZeroFiveUp || roundingOnOverflow == ERounding.OddOrZeroFiveUp || roundingOnOverflow == ERounding.Odd || (roundingOnOverflow == ERounding.Ceiling && neg) || (roundingOnOverflow == ERounding.Floor && !neg))) { // Set to the highest possible value for // the given precision EInteger overflowMant = EInteger.Zero; FastInteger fastPrecision = FastInteger.FromBig(pc.Precision); overflowMant = this.GetHelper().MultiplyByRadixPower( EInteger.One, fastPrecision); overflowMant -= EInteger.One; FastInteger clamp = FastInteger.FromBig(pc.EMax).Increment().Subtract(fastPrecision); return(this.GetHelper().CreateNewWithFlags( overflowMant, clamp.AsEInteger(), neg ? BigNumberFlags.FlagNegative : 0)); } } int flagneg = neg ? BigNumberFlags.FlagNegative : 0; return(this.GetHelper().GetArithmeticSupport() == BigNumberFlags.FiniteOnly ? default(T) : this.GetHelper().CreateNewWithFlags( EInteger.Zero, EInteger.Zero, flagneg | BigNumberFlags.FlagInfinity)); }
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); }
public void ShiftToDigits( FastInteger bits, FastInteger preShift, bool truncate) { #if DEBUG if (bits.Sign < 0) { throw new ArgumentException("bits's sign (" + bits.Sign + ") is less than 0"); } #endif if (preShift != null && preShift.Sign > 0) { FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength(); this.knownDigitLength = kdl; // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" + // (//kdl) + " [" + this.shiftedBigInt + "]"); if (kdl.CompareTo(bits) <= 0) { // Known digit length is already small enough if (truncate) { this.TruncateRight(preShift); } else { this.ShiftRight(preShift); } this.VerifyKnownLength(); return; } else { FastInteger bitDiff = kdl.Copy().Subtract(bits); // DebugUtility.Log("bitDiff=" + bitDiff); int cmp = bitDiff.CompareTo(preShift); if (cmp <= 0) { // Difference between desired digit length and current // length is smaller than the shift, make it the shift if (truncate) { this.TruncateRight(preShift); } else { this.ShiftRight(preShift); } this.VerifyKnownLength(); return; } else { if (truncate) { this.TruncateRight(bitDiff); } else { this.ShiftRight(bitDiff); } this.VerifyKnownLength(); return; } } } if (bits.CanFitInInt32()) { int intval = bits.AsInt32(); if (intval < 0) { throw new ArgumentException("intval (" + intval + ") is less than " + "0"); } if (this.isSmall) { this.ShiftToDigitsSmall(intval); } else { this.ShiftToDigitsBig(intval, truncate); } this.VerifyKnownLength(); } else { FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength(); this.knownDigitLength = kdl; this.VerifyKnownLength(); EInteger bigintDiff = kdl.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(); } }
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(); } }