internal static EInteger FindPowerOfTenFromBig(EInteger
                                                       bigintExponent)
        {
            int sign = bigintExponent.Sign;

            if (sign < 0)
            {
                return(EInteger.Zero);
            }
            if (sign == 0)
            {
                return(EInteger.One);
            }
            if (bigintExponent.CompareTo(ValueBigInt36) <= 0)
            {
                return(FindPowerOfTen((int)bigintExponent));
            }
            FastInteger intcurexp = FastInteger.FromBig(bigintExponent);
            EInteger    mantissa  = EInteger.One;
            EInteger    bigpow    = EInteger.Zero;

            // DebugUtility.Log("Getting power of ten from big "+bigintExponent);
            while (intcurexp.Sign > 0)
            {
                if (intcurexp.CompareToInt(18) <= 0)
                {
                    bigpow    = FindPowerOfTen(intcurexp.AsInt32());
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (intcurexp.CompareToInt(9999999) <= 0)
                {
                    int val = intcurexp.AsInt32();
                    bigpow    = FindPowerOfFive(val);
                    bigpow  <<= val;
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (bigpow.IsZero)
                {
                    bigpow   = FindPowerOfFive(9999999);
                    bigpow <<= 9999999;
                }
                mantissa *= bigpow;
                intcurexp.AddInt(-9999999);
            }
            return(mantissa);
        }
Exemplo n.º 2
0
        public int CompareTo(FastInteger fint)
        {
            switch (this.integerMode)
            {
            case IntegerMode.SmallValue:
                return(-fint.CompareToInt(this.smallValue));

            case IntegerMode.LargeValue:
                return(-fint.CompareTo(this.largeValue));

            default: throw new InvalidOperationException();
            }
        }
Exemplo n.º 3
0
   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 || digits!=null");
       }
 #endif
       if (bigmant.IsZero)
       {
           exponentMutable.SetInt(0);
           return(bigmant);
       }
       var bigradix    = (EInteger)radix;
       var bitToTest   = 0;
       var bitsToShift = new FastInteger(0);
       while (!bigmant.IsZero)
       {
           if (precision != null && digits.CompareTo(precision) == 0)
           {
               break;
           }
           if (idealExp != null && exponentMutable.CompareTo(idealExp) == 0)
           {
               break;
           }
           if (radix == 2)
           {
               if (bitToTest < Int32.MaxValue)
               {
                   if (bigmant.GetSignedBit(bitToTest))
                   {
                       break;
                   }
                   ++bitToTest;
                   bitsToShift.Increment();
               }
               else
               {
                   if (!bigmant.IsEven)
                   {
                       break;
                   }
                   bigmant >>= 1;
               }
           }
           else
           {
               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();
           }
       }
       if (radix == 2 && !bitsToShift.IsValueZero)
       {
           while (bitsToShift.CompareToInt(1000000) > 0)
           {
               bigmant >>= 1000000;
               bitsToShift.SubtractInt(1000000);
           }
           int tmpshift = bitsToShift.AsInt32();
           bigmant >>= tmpshift;
       }
       return(bigmant);
   }
Exemplo n.º 4
0
        internal static EInteger FindPowerOfFiveFromBig(EInteger diff)
        {
            int sign = diff.Sign;

            if (sign < 0)
            {
                return(EInteger.Zero);
            }
            if (sign == 0)
            {
                return(EInteger.One);
            }
            FastInteger intcurexp = FastInteger.FromBig(diff);

            if (intcurexp.CompareToInt(54) <= 0)
            {
                return(FindPowerOfFive(intcurexp.AsInt32()));
            }
            EInteger mantissa = EInteger.One;
            EInteger bigpow;
            EInteger origdiff = diff;

            bigpow = ValuePowerOfFiveCache.GetCachedPower(origdiff);
            if (bigpow != null)
            {
                return(bigpow);
            }
            EInteger[] otherPower =
                ValuePowerOfFiveCache.FindCachedPowerOrSmaller(origdiff);
            if (otherPower != null)
            {
                intcurexp.SubtractBig(otherPower[0]);
                bigpow   = otherPower[1];
                mantissa = bigpow;
            }
            else
            {
                bigpow = EInteger.Zero;
            }
            while (intcurexp.Sign > 0)
            {
                if (intcurexp.CompareToInt(27) <= 0)
                {
                    bigpow    = FindPowerOfFive(intcurexp.AsInt32());
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (intcurexp.CompareToInt(9999999) <= 0)
                {
                    bigpow    = FindPowerOfFive(1).Pow(intcurexp.AsInt32());
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (bigpow.IsZero)
                {
                    bigpow = FindPowerOfFive(1).Pow(9999999);
                }
                mantissa *= bigpow;
                intcurexp.AddInt(-9999999);
            }
            ValuePowerOfFiveCache.AddPower(origdiff, mantissa);
            return(mantissa);
        }
Exemplo n.º 5
0
        private void ShiftToDigitsBig(int digits, bool truncate)
        {
            // Shifts a number until it reaches the given number of digits,
            // gathering information on whether the last digit discarded is set
            // and whether the discarded digits to the right of that digit are set.
            // Assumes that the big integer being shifted is positive.
            if (this.knownDigitLength != null)
            {
                if (this.knownDigitLength.CompareToInt(digits) <= 0)
                {
                    return;
                }
            }
            string str;

            this.knownDigitLength = this.knownDigitLength ??
                                    this.CalcKnownDigitLength();
            if (this.knownDigitLength.CompareToInt(digits) <= 0)
            {
                return;
            }
            FastInteger digitDiff = this.knownDigitLength.Copy().SubtractInt(digits);

            if (truncate && digitDiff.CanFitInInt32())
            {
                this.TruncateRight(digitDiff);
                return;
            }
            if (digitDiff.CompareToInt(1) == 0)
            {
                EInteger   bigrem;
                EInteger   bigquo;
                EInteger[] divrem = this.shiftedBigInt.DivRem(ValueTen);
                bigquo = divrem[0];
                bigrem = divrem[1];
                this.bitsAfterLeftmost |= this.bitLeftmost;
                this.bitLeftmost        = (int)bigrem;
                this.shiftedBigInt      = bigquo;
                this.discardedBitCount  = this.discardedBitCount ?? (new FastInteger(0));
                this.discardedBitCount.Add(digitDiff);
                this.UpdateKnownLength(digitDiff);
                this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0;
                return;
            }
            if (digitDiff.CompareToInt(9) <= 0)
            {
                EInteger   bigrem;
                int        diffInt    = digitDiff.AsInt32();
                EInteger   radixPower = NumberUtility.FindPowerOfTen(diffInt);
                EInteger   bigquo;
                EInteger[] divrem = this.shiftedBigInt.DivRem(radixPower);
                bigquo = divrem[0];
                bigrem = divrem[1];
                var rem = (int)bigrem;
                this.bitsAfterLeftmost |= this.bitLeftmost;
                for (var i = 0; i < diffInt; ++i)
                {
                    if (i == diffInt - 1)
                    {
                        this.bitLeftmost = rem % 10;
                    }
                    else
                    {
                        int intQuot = (rem < 43698) ? ((rem * 26215) >> 18) : (rem / 10);
                        this.bitsAfterLeftmost |= rem - (intQuot * 10);
                        rem = intQuot;
                    }
                }
                this.shiftedBigInt     = bigquo;
                this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0));
                this.discardedBitCount.Add(digitDiff);
                this.UpdateKnownLength(digitDiff);
                this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0;
                return;
            }
            if (digitDiff.CanFitInInt32())
            {
#if DEBUG
                if (!(digitDiff.CompareToInt(2) > 0))
                {
                    throw new ArgumentException(
                              "doesn't satisfy digitDiff.CompareToInt(2)>0");
                }
#endif
                EInteger   bigrem = null;
                EInteger   bigquo;
                EInteger[] divrem;
                if (!this.shiftedBigInt.IsEven || this.bitsAfterLeftmost != 0)
                {
                    EInteger radixPower =
                        NumberUtility.FindPowerOfTen(digitDiff.AsInt32() - 1);
                    this.bitsAfterLeftmost |= 1;
                    bigquo = this.shiftedBigInt.Divide(radixPower);
                }
                else
                {
                    EInteger radixPower =
                        NumberUtility.FindPowerOfTen(digitDiff.AsInt32() - 1);
                    divrem = this.shiftedBigInt.DivRem(radixPower);
                    bigquo = divrem[0];
                    bigrem = divrem[1];
                    this.bitsAfterLeftmost |= this.bitLeftmost;
                    if (!bigrem.IsZero)
                    {
                        this.bitsAfterLeftmost |= 1;
                    }
                }
                EInteger bigquo2;
                divrem                 = bigquo.DivRem(ValueTen);
                bigquo2                = divrem[0];
                bigrem                 = divrem[1];
                this.bitLeftmost       = (int)bigrem;
                this.shiftedBigInt     = bigquo2;
                this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0));
                this.discardedBitCount.Add(digitDiff);
                this.UpdateKnownLength(digitDiff);
                this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0;
                return;
            }
            str = this.shiftedBigInt.ToString();
            // NOTE: Will be 1 if the value is 0
            int digitLength = str.Length;
            this.knownDigitLength = new FastInteger(digitLength);
            // Shift by the difference in digit length
            if (digitLength > digits)
            {
                int digitShift = digitLength - digits;
                this.UpdateKnownLengthInt(digitShift);
                var newLength = (int)(digitLength - digitShift);
                // Console.WriteLine("dlen= " + digitLength + " dshift=" +
                // digitShift + " newlen= " + newLength);
                this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0));
                if (digitShift <= Int32.MaxValue)
                {
                    this.discardedBitCount.AddInt((int)digitShift);
                }
                else
                {
                    this.discardedBitCount.AddBig((EInteger)digitShift);
                }
                for (int i = str.Length - 1; i >= 0; --i)
                {
                    this.bitsAfterLeftmost |= this.bitLeftmost;
                    this.bitLeftmost        = (int)(str[i] - '0');
                    --digitShift;
                    if (digitShift <= 0)
                    {
                        break;
                    }
                }
                if (newLength <= 9)
                {
                    this.isSmall      = true;
                    this.shiftedSmall = FastParseLong(str, 0, newLength);
                }
                else
                {
                    this.shiftedBigInt = EInteger.FromSubstring(str, 0, newLength);
                }
                this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0;
            }
        }
        internal static EInteger FindPowerOfFiveFromBig(EInteger diff)
        {
            int sign = diff.Sign;

            if (sign < 0)
            {
                return(EInteger.Zero);
            }
            if (sign == 0)
            {
                return(EInteger.One);
            }
            FastInteger intcurexp = FastInteger.FromBig(diff);

            if (intcurexp.CompareToInt(54) <= 0)
            {
                return(FindPowerOfFive(intcurexp.AsInt32()));
            }
            // DebugUtility.Log("Getting power of five from big "+diff);
            EInteger mantissa = EInteger.One;
            EInteger bigpow;
            EInteger origdiff = diff;

            bigpow = ValuePowerOfFiveCache.GetCachedPower(origdiff);
            if (bigpow != null)
            {
                return(bigpow);
            }
            EInteger[] otherPower =
                ValuePowerOfFiveCache.FindCachedPowerOrSmaller(origdiff);
            if (otherPower != null)
            {
                // DebugUtility.Log("Found cached power " +otherPower[0]+", "
                // +otherPower[1]);
                intcurexp.SubtractBig(otherPower[0]);
                bigpow   = otherPower[1];
                mantissa = bigpow;
            }
            else
            {
                bigpow = EInteger.Zero;
            }
            while (intcurexp.Sign > 0)
            {
                if (intcurexp.CompareToInt(27) <= 0)
                {
                    bigpow    = FindPowerOfFive(intcurexp.AsInt32());
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (intcurexp.CompareToInt(9999999) <= 0)
                {
                    int icurexp     = intcurexp.AsInt32();
                    int halficurexp = icurexp / 2;
                    bigpow = FindPowerOfFive(halficurexp);
                    bigpow = bigpow.Multiply(
                        FindPowerOfFive(icurexp - halficurexp));
                    mantissa *= (EInteger)bigpow;
                    break;
                }
                if (bigpow.IsZero)
                {
                    bigpow = FindPowerOfFive(1).Pow(9999999);
                }
                mantissa *= bigpow;
                intcurexp.AddInt(-9999999);
            }
            ValuePowerOfFiveCache.AddPower(origdiff, mantissa);
            return(mantissa);
        }