public TrappableRadixMath(IRadixMath <T> math) { #if DEBUG if (math == null) { throw new ArgumentNullException("math"); } #endif this.math = math; }
public SimpleRadixMath(IRadixMath <T> wrapper) { this.wrapper = wrapper; }
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); }