public void ShiftRight(FastInteger fastint) { if (fastint.Sign <= 0) { return; } if (fastint.CanFitInInt32()) { this.ShiftRightInt(fastint.ToInt32()); } else { EInteger bi = fastint.ToEInteger(); 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.ToInt32())); } else { return(FastIntegerFixed.FromBig(fi.ToEInteger())); } }
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); 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); VerifyKnownLength(); return; } else { // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(bitDiff); VerifyKnownLength(); return; } } } if (bits.CanFitInInt32()) { this.ShiftToDigitsInt(bits.ToInt32()); VerifyKnownLength(); } else { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); EInteger bigintDiff = this.knownBitLength.ToEInteger(); EInteger bitsBig = bits.ToEInteger(); bigintDiff -= (EInteger)bitsBig; if (bigintDiff.Sign > 0) { // current length is greater than the // desired bit length this.ShiftRight(FastInteger.FromBig(bigintDiff)); } VerifyKnownLength(); } }
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 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 |= EContext.FlagUnderflow | EContext.FlagSubnormal | EContext.FlagInexact | EContext.FlagRounded; } } } 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().GetDigitLength(mant); 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.ToEInteger(), 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.ToEInteger(), thisFlags); } return(thisValue); }