Example #1
0
        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 });
            }
        }
Example #2
0
        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));
            }
        }
Example #3
0
        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);
        }
Example #4
0
        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);
 }
Example #6
0
        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);
        }
Example #7
0
 public static FastInteger DigitLengthUpperBound <THelper>(
     IRadixMathHelper <THelper> helper,
     EInteger ei)
 {
     return(DigitLengthBounds(helper, ei)[1]);
 }