Example #1
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);
     }
 }
Example #2
0
 public void ShiftRight(FastInteger fastint)
 {
     if (fastint.Sign <= 0)
     {
         return;
     }
     if (fastint.CanFitInInt32())
     {
         this.ShiftRightInt(fastint.ToInt32());
     }
     else
     {
         EInteger bi = fastint.ToEInteger();
         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;
             }
         }
     }
 }
Example #3
0
 public static FastIntegerFixed FromFastInteger(FastInteger fi)
 {
     if (fi.CanFitInInt32())
     {
         return(FromInt32(fi.ToInt32()));
     }
     else
     {
         return(FastIntegerFixed.FromBig(fi.ToEInteger()));
     }
 }
Example #4
0
 public static FastIntegerFixed FromFastInteger(FastInteger fi)
 {
     if (fi.CanFitInInt32())
     {
         return(new FastIntegerFixed(fi.AsInt32()));
     }
     else
     {
         return(FastIntegerFixed.FromBig(fi.AsEInteger()));
     }
 }
Example #5
0
 public void ShiftRight(FastInteger fastint)
 {
     if (fastint == null)
     {
         throw new ArgumentNullException("fastint");
     }
     if (fastint.CanFitInInt32())
     {
         int fi = fastint.AsInt32();
         if (fi < 0)
         {
             return;
         }
         this.ShiftRightInt(fi);
     }
     else
     {
         if (fastint.Sign <= 0)
         {
             return;
         }
         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;
             }
         }
     }
 }
Example #6
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;
            }
        }
Example #7
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();
            }
        }
Example #8
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);
             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);
                 VerifyKnownLength();
                 return;
             }
             else
             {
                 // NOTE: For BitShiftAccumulator, truncating and shifting
                 // are the same, unlike in DigitShiftAccumulator
                 this.ShiftRight(bitDiff);
                 VerifyKnownLength();
                 return;
             }
         }
     }
     if (bits.CanFitInInt32())
     {
         this.ShiftToDigitsInt(bits.ToInt32());
         VerifyKnownLength();
     }
     else
     {
         this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength();
         EInteger bigintDiff = this.knownBitLength.ToEInteger();
         EInteger bitsBig    = bits.ToEInteger();
         bigintDiff -= (EInteger)bitsBig;
         if (bigintDiff.Sign > 0)
         {
             // current length is greater than the
             // desired bit length
             this.ShiftRight(FastInteger.FromBig(bigintDiff));
         }
         VerifyKnownLength();
     }
 }
Example #9
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.ToInt32();
             bs -= bits;
         }
         else
         {
             FastInteger bitShift =
                 this.knownBitLength.Copy().SubtractInt(bits);
             if (!bitShift.CanFitInInt32())
             {
                 this.ShiftRight(bitShift);
                 return;
             }
             bs = bitShift.ToInt32();
         }
         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;
             long lowestSet = this.shiftedBigInt.GetLowBitAsInt64();
             if (lowestSet == Int64.MaxValue)
             {
                 EInteger lowestSetBit = this.shiftedBigInt.GetLowBitAsEInteger();
                 if (lowestSetBit.CompareTo(bs - 1) < 0)
                 {
                     // 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.CompareTo(bs - 1) > 0)
                 {
                     // Means all discarded bits are zero
                     this.bitLeftmost = 0;
                 }
                 else
                 {
                     // Only the last discarded bit is set
                     this.bitLeftmost = 1;
                 }
             }
             else
             {
                 if (lowestSet < 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 (lowestSet > 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;
     }
 }