예제 #1
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;
             }
         }
     }
 }
예제 #2
0
 public static FastIntegerFixed FromFastInteger(FastInteger fi)
 {
     if (fi.CanFitInInt32())
     {
         return(FromInt32(fi.ToInt32()));
     }
     else
     {
         return(FastIntegerFixed.FromBig(fi.ToEInteger()));
     }
 }
예제 #3
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();
     }
 }
예제 #4
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;
     }
 }