예제 #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 });
            }
        }
예제 #2
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);
        }
예제 #3
0
 private static FastIntegerFixed FastPathDigitLength(
     FastIntegerFixed fei,
     int radix)
 {
     if (fei.CanFitInInt32())
     {
         int ifei = fei.ToInt32();
         if (ifei != Int32.MinValue)
         {
             if (radix == 2)
             {
                 return(FastIntegerFixed.FromInt32((int)BitLength(Math.Abs(ifei))));
             }
             else if (radix == 10)
             {
                 return(FastIntegerFixed.FromInt32(
                            (int)DecimalDigitLength(Math.Abs(ifei))));
             }
         }
     }
     else
     {
         if (radix == 2)
         {
             long i64 = fei.ToEInteger().GetUnsignedBitLengthAsInt64();
             if (i64 != Int64.MaxValue)
             {
                 return(FastIntegerFixed.FromInt64(i64));
             }
         }
         else if (radix == 10)
         {
             EInteger ei  = fei.ToEInteger();
             long     i64 = ei.GetUnsignedBitLengthAsInt64();
             if (i64 < 33)
             {
                 // Can easily be calculated without estimation
                 return(FastIntegerFixed.FromInt32(
                            (int)ei.GetDigitCountAsInt64()));
             }
             else if (i64 <= 2135)
             {
                 var bitlen = (int)i64;
                 // Approximation of ln(2)/ln(10)
                 int minDigits = 1 + (((bitlen - 1) * 631305) >> 21);
                 int maxDigits = 1 + ((bitlen * 631305) >> 21);
                 if (minDigits == maxDigits)
                 {
                     return(FastIntegerFixed.FromInt32(minDigits));
                 }
             }
             else if (i64 <= 6432162)
             {
                 var bitlen = (int)i64;
                 // Approximation of ln(2)/ln(10)
                 int minDigits = 1 + (int)(((long)(bitlen - 1) * 661971961083L) >>
                                           41);
                 int maxDigits = 1 + (int)(((long)bitlen * 661971961083L) >> 41);
                 if (minDigits == maxDigits)
                 {
                     return(FastIntegerFixed.FromInt32(minDigits));
                 }
             }
         }
     }
     return(null);
 }