public static FastIntegerFixed[] DigitLengthBoundsFixed <THelper>( IRadixMathHelper <THelper> helper, FastIntegerFixed fei) { int radix = helper.GetRadix(); FastIntegerFixed fastpath = FastPathDigitLength(fei, radix); if (fastpath != null) { return(new FastIntegerFixed[] { fastpath, fastpath }); } if (radix == 10) { EInteger[] fi = DecimalDigitLengthBoundsAsEI(fei.ToEInteger()); return(new FastIntegerFixed[] { FastIntegerFixed.FromBig(fi[0]), FastIntegerFixed.FromBig(fi[1]), }); } else { FastInteger fi = helper.GetDigitLength(fei.ToEInteger()); FastIntegerFixed fif = FastIntegerFixed.FromFastInteger(fi); return(new FastIntegerFixed[] { fif, fif }); } }
public static EInteger IntegerDigitLengthUpperBound <THelper>( IRadixMathHelper <THelper> helper, THelper val) { // Gets an upper bound on the number of digits in the integer // part of the given number 'val'. int flags = helper.GetFlags(val); if ((flags & BigNumberFlags.FlagSpecial) != 0) { // Infinity and NaN are not supported throw new NotSupportedException(); } EInteger expo = helper.GetExponent(val); EInteger mant = helper.GetMantissa(val).Abs(); if (expo.Sign <= 0) { // Exponent Y in X*digits^Y is 0 or negative, so upper bound // of significand's digit count works by itself. return(DigitLengthUpperBound(helper, mant).ToEInteger()); } else { return(DigitLengthUpperBound(helper, mant).ToEInteger().Add(expo)); } }
public static FastIntegerFixed DigitLengthFixed <THelper>( IRadixMathHelper <THelper> helper, FastIntegerFixed fei) { FastIntegerFixed fastpath = FastPathDigitLength(fei, helper.GetRadix()); if (fastpath != null) { return(fastpath); } FastInteger fi = helper.GetDigitLength(fei.ToEInteger()); FastIntegerFixed fif = FastIntegerFixed.FromFastInteger(fi); return(fif); }
public static FastInteger[] DigitLengthBounds <THelper>( IRadixMathHelper <THelper> helper, EInteger ei) { int radix = helper.GetRadix(); if (radix == 2) { FastInteger fi = FastInteger.FromBig(ei.GetUnsignedBitLengthAsEInteger()); return(new FastInteger[] { fi, fi }); } else if (radix == 10) { return(DecimalDigitLengthBounds(ei)); } else { FastInteger fi = helper.GetDigitLength(ei); return(new FastInteger[] { fi, fi }); } }
public ExtendedOrSimpleRadixMath(IRadixMathHelper <T> helper) { this.ext = new RadixMath <T>(helper); this.simp = new SimpleRadixMath <T>(this.ext); }
public static THelper PreRound <THelper>( THelper val, EContext ctx, IRadixMath <THelper> wrapper) { if (ctx == null || !ctx.HasMaxPrecision) { return(val); } IRadixMathHelper <THelper> helper = wrapper.GetHelper(); int thisFlags = helper.GetFlags(val); if ((thisFlags & BigNumberFlags.FlagSpecial) != 0) { // Infinity or NaN return(val); } FastInteger fastPrecision = FastInteger.FromBig(ctx.Precision); EInteger mant = helper.GetMantissa(val).Abs(); // 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) FastInteger[] digitBounds = NumberUtility.DigitLengthBounds( helper, mant); if (digitBounds[1].CompareTo(fastPrecision) <= 0) { // Upper bound is less than or equal to precision return(val); } EContext ctx2 = ctx; if (digitBounds[0].CompareTo(fastPrecision) <= 0) { // Lower bound is less than or equal to precision, so // calculate digit length more precisely FastInteger digits = helper.GetDigitLength(mant); ctx2 = ctx.WithBlankFlags().WithTraps(0); if (digits.CompareTo(fastPrecision) <= 0) { return(val); } } val = wrapper.RoundToPrecision(val, ctx2); // the only time rounding can signal an invalid // operation is if an operand is a signaling NaN, but // this was already checked beforehand #if DEBUG if ((ctx2.Flags & EContext.FlagInvalid) != 0) { throw new ArgumentException("doesn't" + "\u0020satisfy(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.FlagOverflow) != 0) { bool neg = (thisFlags & BigNumberFlags.FlagNegative) != 0; if (ctx.HasFlags) { ctx.Flags |= EContext.FlagLostDigits; ctx.Flags |= EContext.FlagOverflow | EContext.FlagInexact | EContext.FlagRounded; } } return(val); }
public static FastInteger DigitLengthUpperBound <THelper>( IRadixMathHelper <THelper> helper, EInteger ei) { return(DigitLengthBounds(helper, ei)[1]); }