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);
        }
Exemple #2
0
 public void TruncateRight(FastInteger fastint)
 {
     if (fastint == null)
     {
         throw new ArgumentNullException("fastint");
     }
     if (fastint.CanFitInInt32())
     {
         int fi = fastint.AsInt32();
         if (fi < 0)
         {
             return;
         }
         if (!this.isSmall)
         {
             if (this.shiftedBigInt.CanFitInInt64())
             {
                 this.TruncateRightLong(this.shiftedBigInt.ToInt64Checked(), fi);
             }
             else
             {
                 this.ShiftRightBig(fi, true);
             }
         }
         else
         {
             this.TruncateRightSmall(fi);
         }
     }
     else
     {
         this.ShiftRight(fastint);
     }
 }
Exemple #3
0
 public void ShiftRight(FastInteger fastint)
 {
     if (fastint.Sign <= 0)
     {
         return;
     }
     if (fastint.CanFitInInt32())
     {
         this.ShiftRightInt(fastint.AsInt32());
     }
     else
     {
         EInteger bi = fastint.AsEInteger();
         while (bi.Sign > 0)
         {
             var count = 1000000;
             if (bi.CompareTo((EInteger)1000000) < 0)
             {
                 count = (int)bi;
             }
             this.ShiftRightInt(count);
             bi -= (EInteger)count;
             if (this.isSmall ? this.shiftedSmall == 0 :
                 this.shiftedBigInt.IsZero)
             {
                 break;
             }
         }
     }
 }
Exemple #4
0
 public static FastIntegerFixed FromFastInteger(FastInteger fi)
 {
     if (fi.CanFitInInt32())
     {
         return(FromInt32(fi.AsInt32()));
     }
     else
     {
         return(FastIntegerFixed.FromBig(fi.AsEInteger()));
     }
 }
Exemple #5
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);
   }
Exemple #6
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);
        }
Exemple #7
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;
            }
        }
Exemple #8
0
        public void ShiftToDigits(
            FastInteger bits,
            FastInteger preShift,
            bool truncate)
        {
#if DEBUG
            if (bits.Sign < 0)
            {
                throw new ArgumentException("bits's sign (" + bits.Sign +
                                            ") is less than 0");
            }
#endif
            if (preShift != null && preShift.Sign > 0)
            {
                FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength();
                this.knownDigitLength = kdl;
                // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" +
                // (//kdl) + " [" + this.shiftedBigInt + "]");
                if (kdl.CompareTo(bits) <= 0)
                {
                    // Known digit length is already small enough
                    if (truncate)
                    {
                        this.TruncateRight(preShift);
                    }
                    else
                    {
                        this.ShiftRight(preShift);
                    }
                    this.VerifyKnownLength();
                    return;
                }
                else
                {
                    FastInteger bitDiff = kdl.Copy().Subtract(bits);
                    // DebugUtility.Log("bitDiff=" + bitDiff);
                    int cmp = bitDiff.CompareTo(preShift);
                    if (cmp <= 0)
                    {
                        // Difference between desired digit length and current
                        // length is smaller than the shift, make it the shift
                        if (truncate)
                        {
                            this.TruncateRight(preShift);
                        }
                        else
                        {
                            this.ShiftRight(preShift);
                        }
                        this.VerifyKnownLength();
                        return;
                    }
                    else
                    {
                        if (truncate)
                        {
                            this.TruncateRight(bitDiff);
                        }
                        else
                        {
                            this.ShiftRight(bitDiff);
                        }
                        this.VerifyKnownLength();
                        return;
                    }
                }
            }
            if (bits.CanFitInInt32())
            {
                int intval = bits.AsInt32();
                if (intval < 0)
                {
                    throw new ArgumentException("intval (" + intval + ") is less than " +
                                                "0");
                }
                if (this.isSmall)
                {
                    this.ShiftToDigitsSmall(intval);
                }
                else
                {
                    this.ShiftToDigitsBig(intval, truncate);
                }
                this.VerifyKnownLength();
            }
            else
            {
                FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength();
                this.knownDigitLength = kdl;
                this.VerifyKnownLength();
                EInteger bigintDiff = kdl.AsEInteger();
                EInteger bitsBig    = bits.AsEInteger();
                bigintDiff -= (EInteger)bitsBig;
                if (bigintDiff.Sign > 0)
                {
                    // current length is greater than the
                    // desired bit length
                    this.ShiftRight(FastInteger.FromBig(bigintDiff));
                }
                this.VerifyKnownLength();
            }
        }
        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);
        }
Exemple #10
0
 private void ShiftBigToBits(int bits)
 {
     // Shifts a number until it reaches the given number of bits,
     // gathering information on whether the last bit discarded is set and
     // whether the discarded bits to the right of that bit are set. Assumes
     // that the big integer being shifted is positive.
     if (this.knownBitLength != null)
     {
         if (this.knownBitLength.CompareToInt(bits) <= 0)
         {
             return;
         }
     }
     this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength();
     if (this.knownBitLength.CompareToInt(bits) <= 0)
     {
         return;
     }
     // Shift by the difference in bit length
     if (this.knownBitLength.CompareToInt(bits) > 0)
     {
         var bs = 0;
         if (this.knownBitLength.CanFitInInt32())
         {
             bs  = this.knownBitLength.AsInt32();
             bs -= bits;
         }
         else
         {
             FastInteger bitShift =
                 this.knownBitLength.Copy().SubtractInt(bits);
             if (!bitShift.CanFitInInt32())
             {
                 this.ShiftRight(bitShift);
                 return;
             }
             bs = bitShift.AsInt32();
         }
         this.knownBitLength.SetInt(bits);
         this.discardedBitCount.AddInt(bs);
         if (bs == 1)
         {
             bool odd = !this.shiftedBigInt.IsEven;
             this.shiftedBigInt    >>= 1;
             this.bitsAfterLeftmost |= this.bitLeftmost;
             this.bitLeftmost        = odd ? 1 : 0;
         }
         else
         {
             this.bitsAfterLeftmost |= this.bitLeftmost;
             int lowestSetBit = this.shiftedBigInt.GetLowBit();
             if (lowestSetBit < bs - 1)
             {
                 // One of the discarded bits after
                 // the last one is set
                 this.bitsAfterLeftmost |= 1;
                 this.bitLeftmost        = this.shiftedBigInt.GetSignedBit(bs - 1) ? 1 : 0;
             }
             else if (lowestSetBit > bs - 1)
             {
                 // Means all discarded bits are zero
                 this.bitLeftmost = 0;
             }
             else
             {
                 // Only the last discarded bit is set
                 this.bitLeftmost = 1;
             }
             this.shiftedBigInt >>= bs;
         }
         if (bits < SmallBitLength)
         {
             // Shifting to small number of bits,
             // convert to small integer
             this.isSmall      = true;
             this.shiftedSmall = (int)this.shiftedBigInt;
         }
         this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0;
     }
 }
Exemple #11
0
 public void ShiftToDigits(
     FastInteger bits,
     FastInteger preShift,
     bool truncate)
 {
     if (bits.Sign < 0)
     {
         throw new ArgumentException("bits's sign(" + bits.Sign +
                                     ") is less than 0");
     }
     if (preShift != null && preShift.Sign > 0)
     {
         this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength();
         // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" +
         // (//kbl) + " [" + this.shiftedBigInt + "]");
         if (this.knownBitLength.CompareTo(bits) <= 0)
         {
             // Known digit length is already small enough
             // NOTE: For BitShiftAccumulator, truncating and shifting
             // are the same, unlike in DigitShiftAccumulator
             this.ShiftRight(preShift);
             this.VerifyKnownLength();
             return;
         }
         else
         {
             FastInteger bitDiff = this.knownBitLength.Copy()
                                   .Subtract(bits);
             // DebugUtility.Log("bitDiff=" + bitDiff);
             int cmp = bitDiff.CompareTo(preShift);
             if (cmp <= 0)
             {
                 // NOTE: For BitShiftAccumulator, truncating and shifting
                 // are the same, unlike in DigitShiftAccumulator
                 this.ShiftRight(preShift);
                 this.VerifyKnownLength();
                 return;
             }
             else
             {
                 // NOTE: For BitShiftAccumulator, truncating and shifting
                 // are the same, unlike in DigitShiftAccumulator
                 this.ShiftRight(bitDiff);
                 this.VerifyKnownLength();
                 return;
             }
         }
     }
     if (bits.CanFitInInt32())
     {
         this.ShiftToDigitsInt(bits.AsInt32());
         this.VerifyKnownLength();
     }
     else
     {
         this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength();
         EInteger bigintDiff = this.knownBitLength.AsEInteger();
         EInteger bitsBig    = bits.AsEInteger();
         bigintDiff -= (EInteger)bitsBig;
         if (bigintDiff.Sign > 0)
         {
             // current length is greater than the
             // desired bit length
             this.ShiftRight(FastInteger.FromBig(bigintDiff));
         }
         this.VerifyKnownLength();
     }
 }