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; } } } }
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 }); } }
private T ReturnQuietNaN(T thisValue, EContext ctx) { EInteger mant = this.GetHelper().GetMantissa(thisValue).Abs(); var mantChanged = false; if (!mant.IsZero && ctx != null && ctx.HasMaxPrecision) { EInteger limit = this.GetHelper().MultiplyByRadixPower( EInteger.One, FastInteger.FromBig(ctx.Precision)); if (mant.CompareTo(limit) >= 0) { mant %= (EInteger)limit; mantChanged = true; } } int flags = this.GetHelper().GetFlags(thisValue); if (!mantChanged && (flags & BigNumberFlags.FlagQuietNaN) != 0) { return(thisValue); } flags &= BigNumberFlags.FlagNegative; flags |= BigNumberFlags.FlagQuietNaN; return(this.GetHelper().CreateNewWithFlags(mant, EInteger.Zero, flags)); }
private FastInteger CalcKnownBitLength() { if (this.isSmall) { int kb = SmallBitLength; for (int i = SmallBitLength - 1; i >= 0; --i) { if ((this.shiftedSmall & (1 << i)) != 0) { break; } --kb; } // Make sure bit length is 1 if value is 0 if (kb == 0) { ++kb; } return(new FastInteger(kb)); } if (this.shiftedBigInt.IsZero) { { return(new FastInteger(1)); } } long sbe = this.shiftedBigInt.GetSignedBitLengthAsInt64(); return((sbe < Int32.MaxValue) ? new FastInteger((int)sbe) : FastInteger.FromBig(this.shiftedBigInt.GetSignedBitLengthAsEInteger())); }
public FastInteger ToFastInteger() { if (this.integerMode == IntegerMode.SmallValue) { return(new FastInteger(this.smallValue)); } else { return(FastInteger.FromBig(this.largeValue)); } }
public static FastIntegerFixed FromFastInteger(FastInteger fi) { if (fi.CanFitInInt32()) { return(FromInt32(fi.ToInt32())); } else { return(FastIntegerFixed.FromBig(fi.ToEInteger())); } }
public BitShiftAccumulator(BigInteger bigint, int lastDiscarded, int olderDiscarded ) { if (bigint.Sign < 0) throw new ArgumentException("bigint is negative"); shiftedBigInt = bigint; discardedBitCount = new FastInteger(0); bitsAfterLeftmost = (olderDiscarded != 0) ? 1 : 0; bitLeftmost = (lastDiscarded != 0) ? 1 : 0; }
/// <summary>This is an internal API.</summary> /// <returns>A text string.</returns> public override string ToString() { switch (this.integerMode) { case IntegerMode.SmallValue: return(FastInteger.IntToString(this.smallValue)); case IntegerMode.LargeValue: return(this.largeValue.ToString()); default: return(String.Empty); } }
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(); } }
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); }
public BitShiftAccumulator( int smallint, int lastDiscarded, int olderDiscarded) { this.shiftedSmall = smallint; if (this.shiftedSmall < 0) { throw new ArgumentException("shiftedSmall(" + this.shiftedSmall + ") is less than 0"); } this.isSmall = true; this.discardedBitCount = new FastInteger(0); this.bitsAfterLeftmost = (olderDiscarded != 0) ? 1 : 0; this.bitLeftmost = (lastDiscarded != 0) ? 1 : 0; }
private void ShiftRightSmall(int bits) { if (bits <= 0) { return; } if (this.shiftedSmall == 0) { this.discardedBitCount.AddInt(bits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownBitLength = new FastInteger(1); return; } int kb = SmallBitLength; for (int i = SmallBitLength - 1; i >= 0; --i) { if ((this.shiftedSmall & (1 << i)) != 0) { break; } --kb; } var shift = (int)Math.Min(kb, bits); bool shiftingMoreBits = bits > kb; kb -= shift; this.knownBitLength = new FastInteger(kb); this.discardedBitCount.AddInt(bits); this.bitsAfterLeftmost |= this.bitLeftmost; // Get the bottommost shift minus 1 bits this.bitsAfterLeftmost |= (shift > 1 && (this.shiftedSmall << (SmallBitLength - shift + 1)) != 0) ? 1 : 0; // Get the bit just above that bit this.bitLeftmost = (int)((this.shiftedSmall >> (shift - 1)) & 0x01); this.shiftedSmall >>= shift; if (shiftingMoreBits) { // Shifted more bits than the bit length this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; }
public static FastInteger[] DigitLengthBounds <THelper>( IRadixMathHelper <THelper> helper, EInteger ei) { int radix = helper.GetRadix(); if (radix == 2) { FastInteger fi = FastInteger.FromBig(ei.GetUnsignedBitLengthAsEInteger()); return(new FastInteger[] { fi, fi }); } else if (radix == 10) { return(DecimalDigitLengthBounds(ei)); } else { FastInteger fi = helper.GetDigitLength(ei); return(new FastInteger[] { fi, fi }); } }
public BitShiftAccumulator( EInteger bigint, int lastDiscarded, int olderDiscarded) { if (bigint.Sign < 0) { throw new ArgumentException("bigint's sign(" + bigint.Sign + ") is less than 0"); } if (bigint.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = (int)bigint; } else { this.shiftedBigInt = bigint; } this.discardedBitCount = new FastInteger(0); this.bitsAfterLeftmost = (olderDiscarded != 0) ? 1 : 0; this.bitLeftmost = (lastDiscarded != 0) ? 1 : 0; }
private void ShiftSmallToBits(int bits) { if (this.knownBitLength != null) { if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } int kbl = this.knownBitLength.ToInt32(); // Shift by the difference in bit length if (kbl > bits) { int bitShift = kbl - (int)bits; var shift = (int)bitShift; this.knownBitLength = new FastInteger(bits); this.discardedBitCount.AddInt(bitShift); this.bitsAfterLeftmost |= this.bitLeftmost; // Get the bottommost shift minus 1 bits this.bitsAfterLeftmost |= (shift > 1 && (this.shiftedSmall << (SmallBitLength - shift + 1)) != 0) ? 1 : 0; // Get the bit just above that bit this.bitLeftmost = (int)((this.shiftedSmall >> (shift - 1)) & 0x01); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; this.shiftedSmall >>= shift; } else { this.knownBitLength = new FastInteger(kbl); } }
public FastInteger GetDigitLength() { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); return FastInteger.CopyFrozen(this.knownBitLength); }
private void ShiftRightBig(int digits) { if (digits <= 0) return; if (shiftedBigInt.IsZero) { if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(digits); bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; knownBitLength = new FastInteger(1); return; } //Console.WriteLine("digits={0}",digits); if(digits==1){ BigInteger bigrem; BigInteger bigquo=BigInteger.DivRem(shiftedBigInt,(BigInteger)10, out bigrem); bitsAfterLeftmost|=bitLeftmost; bitLeftmost=(int)bigrem; shiftedBigInt=bigquo; if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(digits); if(knownBitLength!=null){ if(bigquo.IsZero) knownBitLength.SetInt(0); else knownBitLength.Decrement(); } return; } int startCount=Math.Min(4,digits-1); if(startCount>0){ BigInteger bigrem; BigInteger radixPower=DecimalUtility.FindPowerOfTen(startCount); BigInteger bigquo=BigInteger.DivRem(shiftedBigInt,radixPower, out bigrem); if(!bigrem.IsZero) bitsAfterLeftmost|=1; bitsAfterLeftmost|=bitLeftmost; shiftedBigInt=bigquo; if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(startCount); digits-=startCount; if(shiftedBigInt.IsZero){ // Shifted all the way to 0 isSmall=true; shiftedSmall=0; knownBitLength=new FastInteger(1); bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; bitLeftmost=0; return; } } String str = shiftedBigInt.ToString(); // NOTE: Will be 1 if the value is 0 int digitLength = str.Length; int bitDiff = 0; if (digits > digitLength) { bitDiff = digits - digitLength; } if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(digits); bitsAfterLeftmost |= bitLeftmost; int digitShift = Math.Min(digitLength, digits); if (digits >= digitLength) { isSmall = true; shiftedSmall = 0; knownBitLength = new FastInteger(1); } else { int newLength = (int)(digitLength - digitShift); knownBitLength = new FastInteger(newLength); if (newLength <= 9) { // Fits in a small number isSmall = true; shiftedSmall = FastParseLong(str, 0, newLength); } else { shiftedBigInt = BigInteger.fromSubstring(str, 0, newLength); } } for (int i = str.Length - 1; i >= 0; i--) { bitsAfterLeftmost |= bitLeftmost; bitLeftmost = (int)(str[i] - '0'); digitShift--; if (digitShift <= 0) { break; } } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; if (bitDiff > 0) { // Shifted more digits than the digit length bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; } }
private void ShiftRightSmall(int digits) { if (digits <= 0) return; if (shiftedSmall == 0) { if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(digits); bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; knownBitLength = new FastInteger(1); return; } int kb = 0; int tmp = shiftedSmall; while (tmp > 0) { kb++; tmp /= 10; } // Make sure digit length is 1 if value is 0 if (kb == 0) kb++; knownBitLength=new FastInteger(kb); if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.AddInt(digits); while (digits > 0) { if (shiftedSmall == 0) { bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; knownBitLength = new FastInteger(0); break; } else { int digit = (int)(shiftedSmall % 10); bitsAfterLeftmost |= bitLeftmost; bitLeftmost = digit; digits--; shiftedSmall /= 10; knownBitLength.Decrement(); } } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; }
public static THelper PreRound <THelper>( THelper val, EContext ctx, IRadixMath <THelper> wrapper) { if (ctx == null || !ctx.HasMaxPrecision) { return(val); } IRadixMathHelper <THelper> helper = wrapper.GetHelper(); int thisFlags = helper.GetFlags(val); if ((thisFlags & BigNumberFlags.FlagSpecial) != 0) { // Infinity or NaN return(val); } FastInteger fastPrecision = FastInteger.FromBig(ctx.Precision); EInteger mant = helper.GetMantissa(val).Abs(); // Rounding is only to be done if the digit count is // too big (distinguishing this case is material // if the value also has an exponent that's out of range) FastInteger[] digitBounds = NumberUtility.DigitLengthBounds( helper, mant); if (digitBounds[1].CompareTo(fastPrecision) <= 0) { // Upper bound is less than or equal to precision return(val); } EContext ctx2 = ctx; if (digitBounds[0].CompareTo(fastPrecision) <= 0) { // Lower bound is less than or equal to precision, so // calculate digit length more precisely FastInteger digits = helper.GetDigitLength(mant); ctx2 = ctx.WithBlankFlags().WithTraps(0); if (digits.CompareTo(fastPrecision) <= 0) { return(val); } } val = wrapper.RoundToPrecision(val, ctx2); // the only time rounding can signal an invalid // operation is if an operand is a signaling NaN, but // this was already checked beforehand #if DEBUG if ((ctx2.Flags & EContext.FlagInvalid) != 0) { throw new ArgumentException("doesn't" + "\u0020satisfy(ctx2.Flags&FlagInvalid)==0"); } #endif if ((ctx2.Flags & EContext.FlagInexact) != 0) { if (ctx.HasFlags) { ctx.Flags |= BigNumberFlags.LostDigitsFlags; } } if ((ctx2.Flags & EContext.FlagRounded) != 0) { if (ctx.HasFlags) { ctx.Flags |= EContext.FlagRounded; } } if ((ctx2.Flags & EContext.FlagOverflow) != 0) { bool neg = (thisFlags & BigNumberFlags.FlagNegative) != 0; if (ctx.HasFlags) { ctx.Flags |= EContext.FlagLostDigits; ctx.Flags |= EContext.FlagOverflow | EContext.FlagInexact | EContext.FlagRounded; } } return(val); }
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(); } }
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; }
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; } }
private void ShiftToDigitsSmall(int digits) { var kb = 0; int v2 = this.shiftedSmall; kb = (v2 >= 1000000000) ? 10 : ((v2 >= 100000000) ? 9 : ((v2 >= 10000000) ? 8 : ((v2 >= 1000000) ? 7 : ((v2 >= 100000) ? 6 : ((v2 >= 10000) ? 5 : ((v2 >= 1000) ? 4 : ((v2 >= 100) ? 3 : ((v2 >= 10) ? 2 : 1)))))))); this.knownDigitLength = new FastInteger(kb); if (kb > digits) { var digitShift = (int)(kb - digits); this.UpdateKnownLengthInt(digitShift); this.discardedBitCount = this.discardedBitCount != null ? this.discardedBitCount.AddInt(digitShift) : (new FastInteger(digitShift)); for (var i = 0; i < digitShift; ++i) { var digit = (int)(this.shiftedSmall % 10); this.shiftedSmall /= 10; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = digit; } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; } }
private void ShiftRightLong(long shiftedLong, int digits) { if (digits <= 0) { return; } if (shiftedLong == 0) { this.shiftedSmall = 0; this.isSmall = true; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 2 && digits <= 8) { if (shiftedLong >= ValueTenPowers[digits]) { long bigPower = ValueTenPowers[digits]; long smallPower = ValueTenPowers[digits - 1]; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); long div = shiftedLong / bigPower; long rem = shiftedLong - (div * bigPower); long rem2 = rem / smallPower; this.bitLeftmost = (int)rem2; this.bitsAfterLeftmost |= ((rem - (rem2 * smallPower)) == 0) ? 0 : 1; this.isSmall = div <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)div; this.knownDigitLength = (div < 10) ? (new FastInteger(1)) : new FastInteger(LongDigitLength(div)); } else { this.shiftedBigInt = EInteger.FromInt64(div); this.knownDigitLength = (div < 10) ? (new FastInteger(1)) : this.CalcKnownDigitLength(); } return; } else if (this.shiftedSmall >= ValueTenPowers[digits - 1]) { int smallPower = ValueTenPowers[digits - 1]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } long rem = shiftedLong; long rem2 = rem / smallPower; this.bitLeftmost = (int)rem2; this.bitsAfterLeftmost |= ((rem - (rem2 * smallPower)) == 0) ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitLeftmost = 0; this.bitsAfterLeftmost |= (shiftedLong == 0) ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } } this.knownDigitLength = new FastInteger( LongDigitLength(shiftedLong)); if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } var digitsShifted = 0; while (digits > 0) { if (shiftedLong == 0) { this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; break; } else { long newShift = (shiftedLong < 43698) ? ((shiftedLong * 26215) >> 18) : (shiftedLong / 10); var digit = (int)(shiftedLong - (newShift * 10)); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = digit; --digits; ++digitsShifted; shiftedLong = newShift; } } this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digitsShifted); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; }
private void ShiftRightSmall(int digits) { if (digits <= 0) { return; } if (this.shiftedSmall == 0) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 2 && digits <= 8) { if (this.shiftedSmall >= ValueTenPowers[digits]) { int bigPower = ValueTenPowers[digits]; int smallPower = ValueTenPowers[digits - 1]; this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); int div = this.shiftedSmall / bigPower; int rem = this.shiftedSmall - (div * bigPower); int rem2 = rem / smallPower; this.bitLeftmost = rem2; this.bitsAfterLeftmost |= rem - (rem2 * smallPower); this.shiftedSmall = div; this.knownDigitLength = (div < 10) ? (new FastInteger(1)) : this.CalcKnownDigitLength(); return; } else if (this.shiftedSmall >= ValueTenPowers[digits - 1]) { int smallPower = ValueTenPowers[digits - 1]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } int rem = this.shiftedSmall; int rem2 = rem / smallPower; this.bitLeftmost = rem2; this.bitsAfterLeftmost |= rem - (rem2 * smallPower); this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } int rem = this.shiftedSmall; this.bitLeftmost = 0; this.bitsAfterLeftmost |= rem; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } } int v2 = this.shiftedSmall; int kb = (v2 >= 1000000000) ? 10 : ((v2 >= 100000000) ? 9 : ((v2 >= 10000000) ? 8 : ((v2 >= 1000000) ? 7 : ((v2 >= 100000) ? 6 : ((v2 >= 10000) ? 5 : ((v2 >= 1000) ? 4 : ((v2 >= 100) ? 3 : ((v2 >= 10) ? 2 : 1)))))))); this.knownDigitLength = new FastInteger(kb); if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } var digitsShifted = 0; while (digits > 0) { if (this.shiftedSmall == 0) { this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); break; } else { var digit = (int)(this.shiftedSmall % 10); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = digit; --digits; ++digitsShifted; this.shiftedSmall /= 10; } } this.UpdateKnownLengthInt(digitsShifted); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; }
private void ShiftRightBig(int digits, bool truncate) { if (digits <= 0) { return; } if (this.shiftedBigInt.IsZero) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); return; } if (truncate) { EInteger bigquo; if (digits > 50) { // To avoid having to calculate a very big power of 10, // check the digit count to see if doing so can be avoided int bitLength = this.shiftedBigInt.GetUnsignedBitLength(); var bigPower = false; // 10^48 has 160 bits; 10^98 has 326; bit length is cheaper // to calculate than base-10 digit length if (bitLength < 160 || (digits > 100 && bitLength < 326)) { bigPower = true; } else { FastInteger knownDigits = this.GetDigitLength(); bigPower = knownDigits.Copy().SubtractInt(digits) .CompareToInt(-2) < 0; if (!bigPower) { // DebugUtility.Log("digitlength {0} [todiscard: {1}]" // , knownDigits, digits); } } if (bigPower) { // Power of 10 to be divided would be much bigger this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.bitLeftmost = 0; this.knownDigitLength = new FastInteger(1); this.isSmall = true; this.shiftedSmall = 0; return; } } if (this.shiftedBigInt.IsEven && this.bitLeftmost == 0) { EInteger[] quorem = this.shiftedBigInt.DivRem( NumberUtility.FindPowerOfTen(digits)); bigquo = quorem[0]; this.bitLeftmost |= quorem[1].IsZero ? 0 : 1; } else { this.bitLeftmost = 1; bigquo = this.shiftedBigInt.Divide( NumberUtility.FindPowerOfTen(digits)); } this.bitsAfterLeftmost |= this.bitLeftmost; this.discardedBitCount = this.discardedBitCount == null ? new FastInteger(digits) : this.discardedBitCount.AddInt(digits); if (bigquo.IsZero) { // Shifted all the way to 0 this.isSmall = true; this.shiftedBigInt = null; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); } else if (bigquo.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = bigquo.ToInt32Unchecked(); this.shiftedBigInt = null; this.UpdateKnownLengthInt(digits); } else { this.isSmall = false; this.shiftedBigInt = bigquo; this.UpdateKnownLengthInt(digits); } return; } if (digits == 1) { EInteger bigrem; EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem((EInteger)10); 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.AddInt(digits); this.UpdateKnownLengthInt(digits); return; } if (digits >= 2 && digits <= 8) { EInteger bigrem; EInteger bigquo; EInteger[] divrem = this.shiftedBigInt.DivRem(NumberUtility.FindPowerOfTen(digits)); bigquo = divrem[0]; bigrem = divrem[1]; var intRem = (int)bigrem; int smallPower = ValueTenPowers[digits - 1]; int leftBit = intRem / smallPower; int otherBits = intRem - (leftBit * smallPower); this.bitsAfterLeftmost |= otherBits | this.bitLeftmost; this.bitLeftmost = leftBit; this.shiftedBigInt = bigquo; this.discardedBitCount = (this.discardedBitCount != null) ? this.discardedBitCount.AddInt(digits) : (new FastInteger(digits)); this.UpdateKnownLengthInt(digits); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; if (this.shiftedBigInt.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = this.shiftedBigInt.ToInt32Unchecked(); this.shiftedBigInt = null; } return; } this.knownDigitLength = this.knownDigitLength ?? this.CalcKnownDigitLength(); if (new FastInteger(digits).Decrement().CompareTo(this.knownDigitLength) >= 0) { // Shifting more bits than available this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; return; } if (this.shiftedBigInt.CanFitInInt32()) { this.isSmall = true; this.shiftedSmall = (int)this.shiftedBigInt; this.ShiftRightSmall(digits); return; } if (this.shiftedBigInt.CanFitInInt64()) { this.ShiftRightLong(this.shiftedBigInt.ToInt64Unchecked(), digits); return; } string str = this.shiftedBigInt.ToString(); // NOTE: Will be 1 if the value is 0 int digitLength = str.Length; var bitDiff = 0; if (digits > digitLength) { bitDiff = digits - digitLength; } this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; int digitShift = Math.Min(digitLength, digits); if (digits >= digitLength) { this.isSmall = true; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); } else { var newLength = (int)(digitLength - digitShift); if (newLength <= 9) { // Fits in a small number this.isSmall = true; this.shiftedSmall = FastParseLong(str, 0, newLength); } else { this.shiftedBigInt = EInteger.FromSubstring(str, 0, newLength); } this.UpdateKnownLengthInt(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; } } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; if (bitDiff > 0) { // Shifted more digits than the digit length this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; } }
private void UpdateKnownLength(FastInteger digitsFast) { if (this.knownDigitLength != null) { this.knownDigitLength.Subtract(digitsFast); if (this.knownDigitLength.CompareToInt(1) < 0) { this.knownDigitLength.SetInt(1); } this.VerifyKnownLength(); } }
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); } }
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; } }
private void TruncateRightLong(long shiftedLong, int digits) { if (digits <= 0) { return; } if (shiftedLong == 0 || digits >= 21) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = shiftedLong == 0 ? 0 : 1; this.shiftedSmall = 0; this.isSmall = true; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 1 && digits <= TenPowersLong.Length - 1) { if (shiftedLong >= TenPowersLong[digits]) { long bigPower = TenPowersLong[digits]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } long quo = shiftedLong / bigPower; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (shiftedLong & 1) == 1 ? 1 : (shiftedLong - (quo * bigPower) == 0 ? 0 : 1); shiftedLong = quo; this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digits); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = shiftedLong == 0 ? 0 : 1; shiftedLong = 0; this.isSmall = shiftedLong <= Int32.MaxValue; if (this.isSmall) { this.shiftedSmall = (int)shiftedLong; } else { this.shiftedBigInt = EInteger.FromInt64(shiftedLong); } this.UpdateKnownLengthInt(digits); return; } } this.ShiftRightInt(digits); }
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; } }
private void TruncateRightSmall(int digits) { if (digits <= 0) { return; } if (this.shiftedSmall == 0 || digits >= 11) { this.discardedBitCount = this.discardedBitCount ?? (new FastInteger(0)); this.discardedBitCount.AddInt(digits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (this.shiftedSmall == 0) ? 0 : 1; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } if (digits >= 1 && digits <= 8) { if (this.shiftedSmall >= ValueTenPowers[digits]) { int bigPower = ValueTenPowers[digits]; if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitsAfterLeftmost |= this.bitLeftmost; if ((this.shiftedSmall & 1) == 1) { this.bitLeftmost = 1; this.shiftedSmall /= bigPower; } else { int quo = this.shiftedSmall / bigPower; int rem = this.shiftedSmall - (quo * bigPower); this.shiftedSmall = quo; this.bitLeftmost |= (rem == 0) ? 0 : 1; } this.UpdateKnownLengthInt(digits); return; } else { if (this.discardedBitCount != null) { this.discardedBitCount.AddInt(digits); } else { this.discardedBitCount = new FastInteger(digits); } this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = (this.shiftedSmall == 0) ? 0 : 1; this.shiftedSmall = 0; this.knownDigitLength = new FastInteger(1); return; } } this.ShiftRightSmall(digits); }
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(); } }
public FastInteger GetDigitLength() { this.knownDigitLength = this.knownDigitLength ?? this.CalcKnownDigitLength(); return this.knownDigitLength; }
/// <summary> 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. </summary> private void ShiftToBitsBig(int digits) { if(knownBitLength!=null){ if(knownBitLength.CompareToInt(digits)<=0){ return; } } String str; if(knownBitLength==null) knownBitLength=GetDigitLength(); if(knownBitLength.CompareToInt(digits)<=0){ return; } FastInteger digitDiff=FastInteger.Copy(knownBitLength).SubtractInt(digits); if(digitDiff.CompareToInt(1)==0){ BigInteger bigrem; BigInteger bigquo=BigInteger.DivRem(shiftedBigInt,Ten,out bigrem); bitsAfterLeftmost|=bitLeftmost; bitLeftmost=(int)bigrem; shiftedBigInt=bigquo; if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.Add(digitDiff); knownBitLength.Subtract(digitDiff); bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; return; } else if(digitDiff.CompareToInt(9)<=0){ BigInteger bigrem; int diffInt=digitDiff.AsInt32(); BigInteger radixPower=DecimalUtility.FindPowerOfTen(diffInt); BigInteger bigquo=BigInteger.DivRem(shiftedBigInt,radixPower, out bigrem); int rem=(int)bigrem; bitsAfterLeftmost|=bitLeftmost; for(int i=0;i<diffInt;i++){ if(i==diffInt-1){ bitLeftmost=rem%10; } else { bitsAfterLeftmost|=(rem%10); rem/=10; } } shiftedBigInt=bigquo; if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.Add(digitDiff); knownBitLength.Subtract(digitDiff); bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; return; } else if(digitDiff.CompareToInt(Int32.MaxValue)<=0){ BigInteger bigrem; BigInteger radixPower=DecimalUtility.FindPowerOfTen(digitDiff.AsInt32()-1); BigInteger bigquo=BigInteger.DivRem(shiftedBigInt,radixPower, out bigrem); bitsAfterLeftmost|=bitLeftmost; if(!bigrem.IsZero) bitsAfterLeftmost|=1; { BigInteger bigquo2=BigInteger.DivRem(bigquo,Ten,out bigrem); this.bitLeftmost=(int)bigrem; shiftedBigInt=bigquo2; } if(discardedBitCount==null) discardedBitCount=new FastInteger(0); discardedBitCount.Add(digitDiff); knownBitLength.Subtract(digitDiff); bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; return; } str=shiftedBigInt.ToString(); // NOTE: Will be 1 if the value is 0 int digitLength = str.Length; knownBitLength = new FastInteger(digitLength); // Shift by the difference in digit length if (digitLength > digits) { int digitShift = digitLength - digits; knownBitLength.SubtractInt(digitShift); int newLength = (int)(digitLength - digitShift); //Console.WriteLine("dlen={0} dshift={1} newlen={2}",digitLength, // digitShift,newLength); if(discardedBitCount==null) discardedBitCount=new FastInteger(0); if(digitShift<=Int32.MaxValue) discardedBitCount.AddInt((int)digitShift); else discardedBitCount.AddBig((BigInteger)digitShift); for (int i = str.Length - 1; i >= 0; i--) { bitsAfterLeftmost |= bitLeftmost; bitLeftmost = (int)(str[i] - '0'); digitShift--; if (digitShift <= 0) { break; } } if (newLength <= 9) { isSmall = true; shiftedSmall = FastParseLong(str, 0, newLength); } else { shiftedBigInt = BigInteger.fromSubstring(str, 0, newLength); } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; } }
/// <summary> </summary> /// <param name='fastint'>A FastInteger object.</param> /// <returns></returns> public void ShiftRight(FastInteger fastint) { if (fastint.Sign <= 0) return; if (fastint.CanFitInInt32()) { ShiftRightInt(fastint.AsInt32()); } else { BigInteger bi = fastint.AsBigInteger(); while (bi.Sign > 0) { int count = 1000000; if (bi.CompareTo((BigInteger)1000000) < 0) { count = (int)bi; } ShiftRightInt(count); bi -= (BigInteger)count; if(isSmall ? shiftedSmall==0 : shiftedBigInt.IsZero){ break; } } } }
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 ||" + "\u0020digits!=null"); } if (!(bigmant.Sign >= 0)) { throw new ArgumentException("doesn't satisfy bigmant.Sign >= 0"); } #endif if (bigmant.IsZero) { exponentMutable.SetInt(0); return(bigmant); } if (radix == 2) { if (!bigmant.IsEven) { return(bigmant); } long lowbit = bigmant.GetLowBitAsInt64(); if (lowbit != Int64.MaxValue) { if (precision != null && digits.CompareTo(precision) >= 0) { // Limit by digits minus precision EInteger tmp = digits.ToEInteger().Subtract(precision.ToEInteger()); if (tmp.CompareTo(EInteger.FromInt64(lowbit)) < 0) { lowbit = tmp.ToInt64Checked(); } } if (idealExp != null && exponentMutable.CompareTo(idealExp) <= 0) { // Limit by idealExp minus exponentMutable EInteger tmp = idealExp.ToEInteger().Subtract(exponentMutable.ToEInteger()); if (tmp.CompareTo(EInteger.FromInt64(lowbit)) < 0) { lowbit = tmp.ToInt64Checked(); } } bigmant = (lowbit <= Int32.MaxValue) ? bigmant.ShiftRight((int)lowbit) : bigmant.ShiftRight(EInteger.FromInt64(lowbit)); if (digits != null) { digits.SubtractInt64(lowbit); } if (exponentMutable != null) { exponentMutable.AddInt64(lowbit); } return(bigmant); } } var bigradix = (EInteger)radix; var bitsToShift = new FastInteger(0); while (!bigmant.IsZero) { if (precision != null && digits.CompareTo(precision) == 0) { break; } if (idealExp != null && exponentMutable.CompareTo(idealExp) == 0) { break; } 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(); } } return(bigmant); }
/// <summary> </summary> /// <param name='bits'>A FastInteger object.</param> /// <returns></returns> public void ShiftToDigits(FastInteger bits) { if(bits.Sign<0) throw new ArgumentException("bits is negative"); if(bits.CanFitInInt32()){ ShiftToDigitsInt(bits.AsInt32()); } else { knownBitLength=CalcKnownBitLength(); BigInteger bigintDiff=knownBitLength.AsBigInteger(); BigInteger bitsBig=bits.AsBigInteger(); bigintDiff-=(BigInteger)bitsBig; if(bigintDiff.Sign>0){ // current length is greater than the // desired bit length ShiftRight(FastInteger.FromBig(bigintDiff)); } } }
public static FastInteger[] DecimalDigitLengthBounds(EInteger ei) { long longBitLength = ei.GetUnsignedBitLengthAsInt64(); if (longBitLength < 33) { // Can easily be calculated without estimation var fi = new FastInteger((int)ei.GetDigitCountAsInt64()); return(new FastInteger[] { fi, fi }); } else if (longBitLength <= 2135) { var bitlen = (int)longBitLength; int minDigits = 1 + (((bitlen - 1) * 631305) >> 21); int maxDigits = 1 + ((bitlen * 631305) >> 21); if (minDigits == maxDigits) { var fi = new FastInteger(minDigits); return(new FastInteger[] { fi, fi }); } else { return(new FastInteger[] { new FastInteger(minDigits), // lower bound new FastInteger(maxDigits), // upper bound }); } } else if (longBitLength <= 6432162) { var bitlen = (int)longBitLength; // 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) { var fi = new FastInteger(minDigits); return(new FastInteger[] { fi, fi }); } else { return(new FastInteger[] { new FastInteger(minDigits), // lower bound new FastInteger(maxDigits), // upper bound }); } } else { // Bit length is big enough that these bounds will // overestimate or underestimate the true base-10 digit length // as appropriate. EInteger bigBitLength = ei.GetUnsignedBitLengthAsEInteger(); EInteger lowerBound = bigBitLength.Multiply(100).Divide(335); EInteger upperBound = bigBitLength.Divide(3); return(new FastInteger[] { FastInteger.FromBig(lowerBound), // lower bound FastInteger.FromBig(upperBound), // upper bound }); } }
private static FastInteger ByteArrayBitLength(byte[] bytes) { FastInteger fastKB = new FastInteger(bytes.Length).Multiply(8); for (int i = bytes.Length - 1; i >= 0; i--) { int b = (int)bytes[i]; if (b != 0) { if ((b & 0x80) != 0) { break; } if ((b & 0x40) != 0) { fastKB.Decrement(); break; } if ((b & 0x20) != 0) { fastKB.SubtractInt(2); break; } if ((b & 0x10) != 0) { fastKB.SubtractInt(3); break; } if ((b & 0x08) != 0) { fastKB.SubtractInt(4); break; } if ((b & 0x04) != 0) { fastKB.SubtractInt(5); break; } if ((b & 0x02) != 0) { fastKB.SubtractInt(6); break; } if ((b & 0x01) != 0) { fastKB.SubtractInt(7); break; } } fastKB.SubtractInt(8); } // Make sure bit length is 1 if value is 0 if (fastKB.Sign == 0) fastKB.Increment(); return fastKB; }
private void ShiftSmallToBits(int bits) { if (this.knownBitLength != null) { if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } int kbl = this.knownBitLength.AsInt32(); // Shift by the difference in bit length if (kbl > bits) { int bitShift = kbl - (int)bits; var shift = (int)bitShift; this.knownBitLength = new FastInteger(bits); this.discardedBitCount.AddInt(bitShift); this.bitsAfterLeftmost |= this.bitLeftmost; // Get the bottommost shift minus 1 bits this.bitsAfterLeftmost |= (shift > 1 && (this.shiftedSmall << (SmallBitLength - shift + 1)) != 0) ? 1 : 0; // Get the bit just above that bit this.bitLeftmost = (int)((this.shiftedSmall >> (shift - 1)) & 0x01); this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; this.shiftedSmall >>= shift; } else { this.knownBitLength = new FastInteger(kbl); } }
/// <summary> 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. </summary> private void ShiftBigToBits(int bits) { byte[] bytes = shiftedBigInt.ToByteArray(); knownBitLength = ByteArrayBitLength(bytes); // Shift by the difference in bit length if (knownBitLength.CompareToInt(bits) > 0) { FastInteger bitShift = FastInteger.Copy(knownBitLength).SubtractInt(bits); FastInteger tmpBitShift = FastInteger.Copy(bitShift); while (tmpBitShift.Sign > 0 && !shiftedBigInt.IsZero) { int bs = tmpBitShift.MinInt32(1000000); shiftedBigInt >>= bs; tmpBitShift.SubtractInt(bs); } knownBitLength.SetInt(bits); if (bits < SmallBitLength) { // Shifting to small number of bits, // convert to small integer isSmall = true; shiftedSmall = (int)shiftedBigInt; } bitsAfterLeftmost |= bitLeftmost; discardedBitCount.Add(bitShift); for (int i = 0; i < bytes.Length; i++) { if (bitShift.CompareToInt(8)>0) { // Discard all the bits, they come // after the leftmost bit bitsAfterLeftmost |= bytes[i]; bitShift.SubtractInt(8); } else { // 8 or fewer bits left. // Get the bottommost bitShift minus 1 bits bitsAfterLeftmost |= ((bytes[i] << (9 - bitShift.AsInt32())) & 0xFF); // Get the bit just above those bits bitLeftmost = (bytes[i] >> ((bitShift.AsInt32()) - 1)) & 0x01; break; } } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; } }
public void TruncateOrShiftRight(FastInteger fastint, bool truncate) { this.ShiftRight(fastint); }
private void ShiftRightBig(int bits) { if (bits <= 0) return; if (shiftedBigInt.IsZero) { discardedBitCount.AddInt(bits); bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; knownBitLength=new FastInteger(1); return; } byte[] bytes = shiftedBigInt.ToByteArray(); knownBitLength = ByteArrayBitLength(bytes); FastInteger bitDiff = new FastInteger(0); FastInteger bitShift=null; if (knownBitLength.CompareToInt(bits)<0) { bitDiff = new FastInteger(bits).Subtract(knownBitLength); bitShift=FastInteger.Copy(knownBitLength); } else { bitShift=new FastInteger(bits); } if (knownBitLength.CompareToInt(bits)<=0) { isSmall = true; shiftedSmall = 0; knownBitLength.SetInt(1); } else { FastInteger tmpBitShift = FastInteger.Copy(bitShift); while (tmpBitShift.Sign > 0 && !shiftedBigInt.IsZero) { int bs = tmpBitShift.MinInt32(1000000); shiftedBigInt >>= bs; tmpBitShift.SubtractInt(bs); } knownBitLength.Subtract(bitShift); } discardedBitCount.AddInt(bits); bitsAfterLeftmost |= bitLeftmost; for (int i = 0; i < bytes.Length; i++) { if (bitShift.CompareToInt(8)>0) { // Discard all the bits, they come // after the leftmost bit bitsAfterLeftmost |= bytes[i]; bitShift.SubtractInt(8); } else { // 8 or fewer bits left. // Get the bottommost bitShift minus 1 bits bitsAfterLeftmost |= ((bytes[i] << (9 - bitShift.AsInt32())) & 0xFF); // Get the bit just above those bits bitLeftmost = (bytes[i] >> ((bitShift.AsInt32()) - 1)) & 0x01; break; } } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; if (bitDiff.Sign > 0) { // Shifted more bits than the bit length bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; } }
private void ShiftRightBig(int bits) { if (bits <= 0) { return; } if (this.shiftedBigInt.IsZero) { this.discardedBitCount.AddInt(bits); this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = 0; this.isSmall = true; this.shiftedSmall = 0; this.knownBitLength = new FastInteger(1); return; } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); this.discardedBitCount.AddInt(bits); int cmp = this.knownBitLength.CompareToInt(bits); if (cmp < 0) { // too few bits this.bitsAfterLeftmost |= this.bitLeftmost; this.bitsAfterLeftmost |= this.shiftedBigInt.IsZero ? 0 : 1; this.bitLeftmost = 0; this.isSmall = true; this.shiftedSmall = 0; this.knownBitLength = new FastInteger(1); } else { // enough bits in the current value int bs = bits; this.knownBitLength.SubtractInt(bits); 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 (this.knownBitLength.CompareToInt(SmallBitLength) < 0) { // 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; } }
private void ShiftRightSmall(int bits) { if (bits <= 0) return; if (shiftedSmall == 0) { discardedBitCount.AddInt(bits); bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; knownBitLength = new FastInteger(1); return; } int kb = SmallBitLength; for (int i = SmallBitLength-1; i >= 0; i++) { if ((shiftedSmall & (1 << i)) != 0) { break; } else { kb--; } } int shift = (int)Math.Min(kb, bits); bool shiftingMoreBits = (bits > kb); kb = kb - shift; knownBitLength=new FastInteger(kb); discardedBitCount.AddInt(bits); bitsAfterLeftmost |= bitLeftmost; // Get the bottommost shift minus 1 bits bitsAfterLeftmost |= (((shiftedSmall << (SmallBitLength + 1 - shift)) != 0) ? 1 : 0); // Get the bit just above that bit bitLeftmost = (int)((shiftedSmall >> ((shift) - 1)) & 0x01); shiftedSmall >>= shift; if (shiftingMoreBits) { // Shifted more bits than the bit length bitsAfterLeftmost |= bitLeftmost; bitLeftmost = 0; } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; }
public FastInteger GetDigitLength() { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); return(FastInteger.CopyFrozen(this.knownBitLength)); }
private void ShiftToBitsSmall(int digits) { int kb=0; int v2=shiftedSmall; if(v2>=1000000000)kb=10; else if(v2>=100000000)kb=9; else if(v2>=10000000)kb=8; else if(v2>=1000000)kb=7; else if(v2>=100000)kb=6; else if(v2>=10000)kb=5; else if(v2>=1000)kb=4; else if(v2>=100)kb=3; else if(v2>=10)kb=2; else kb=1; knownBitLength=new FastInteger(kb); if (kb > digits) { int digitShift = (int)(kb - digits); int newLength = (int)(kb - digitShift); knownBitLength = new FastInteger(Math.Max(1, newLength)); if(discardedBitCount==null) discardedBitCount=new FastInteger(digitShift); else discardedBitCount.AddInt(digitShift); for (int i = 0; i < digitShift; i++) { int digit = (int)(shiftedSmall % 10); shiftedSmall /= 10; bitsAfterLeftmost |= bitLeftmost; bitLeftmost = digit; } bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; } }
private T PostProcessEx( T thisValue, EContext ctxDest, EContext ctxSrc, bool afterDivision, bool afterQuantize) { int thisFlags = this.GetHelper().GetFlags(thisValue); if (ctxDest != null && ctxSrc != null) { if (ctxDest.HasFlags) { if (!ctxSrc.ClampNormalExponents) { ctxSrc.Flags &= ~EContext.FlagClamped; } ctxDest.Flags |= ctxSrc.Flags; if ((ctxSrc.Flags & EContext.FlagSubnormal) != 0) { // Treat subnormal numbers as underflows ctxDest.Flags |= EContext.FlagUnderflow | EContext.FlagSubnormal | EContext.FlagInexact | EContext.FlagRounded; } } } if ((thisFlags & BigNumberFlags.FlagSpecial) != 0) { return((ctxDest.Flags == 0) ? this.SignalInvalid(ctxDest) : thisValue); } EInteger mant = this.GetHelper().GetMantissa(thisValue).Abs(); if (mant.IsZero) { return(afterQuantize ? this.GetHelper().CreateNewWithFlags( mant, this.GetHelper().GetExponent(thisValue), 0) : this.wrapper.RoundToPrecision( this.GetHelper().ValueOf(0), ctxDest)); } if (afterQuantize) { return(thisValue); } EInteger exp = this.GetHelper().GetExponent(thisValue); if (exp.Sign > 0) { FastInteger fastExp = FastInteger.FromBig(exp); if (ctxDest == null || !ctxDest.HasMaxPrecision) { mant = this.GetHelper().MultiplyByRadixPower(mant, fastExp); return(this.GetHelper().CreateNewWithFlags( mant, EInteger.Zero, thisFlags)); } if (!ctxDest.ExponentWithinRange(exp)) { return(thisValue); } FastInteger prec = FastInteger.FromBig(ctxDest.Precision); FastInteger digits = this.GetHelper().GetDigitLength(mant); prec.Subtract(digits); if (prec.Sign > 0 && prec.CompareTo(fastExp) >= 0) { mant = this.GetHelper().MultiplyByRadixPower(mant, fastExp); return(this.GetHelper().CreateNewWithFlags( mant, EInteger.Zero, thisFlags)); } if (afterDivision) { int radix = this.GetHelper().GetRadix(); mant = NumberUtility.ReduceTrailingZeros( mant, fastExp, radix, null, null, null); thisValue = this.GetHelper().CreateNewWithFlags( mant, fastExp.ToEInteger(), thisFlags); } } else if (afterDivision && exp.Sign < 0) { FastInteger fastExp = FastInteger.FromBig(exp); int radix = this.GetHelper().GetRadix(); mant = NumberUtility.ReduceTrailingZeros( mant, fastExp, radix, null, null, new FastInteger(0)); thisValue = this.GetHelper().CreateNewWithFlags( mant, fastExp.ToEInteger(), thisFlags); } return(thisValue); }
private void ShiftSmallToBits(int bits) { int kbl = SmallBitLength; for (int i = SmallBitLength - 1; i >= 0; i++) { if ((shiftedSmall & (1L << i)) != 0) { break; } else { kbl--; } } if (kbl == 0) kbl++; // Shift by the difference in bit length if (kbl > bits) { int bitShift = kbl - (int)bits; int shift = (int)bitShift; knownBitLength = new FastInteger(bits); discardedBitCount.AddInt(bitShift); bitsAfterLeftmost |= bitLeftmost; // Get the bottommost shift minus 1 bits bitsAfterLeftmost |= (((shiftedSmall << (SmallBitLength + 1 - shift)) != 0) ? 1 : 0); // Get the bit just above that bit bitLeftmost = (int)((shiftedSmall >> (((int)shift) - 1)) & 0x01); bitsAfterLeftmost = (bitsAfterLeftmost != 0) ? 1 : 0; shiftedSmall >>= shift; } else { knownBitLength=new FastInteger(kbl); } }
/// <summary> </summary> /// <returns>A FastInteger object.</returns> public FastInteger GetDigitLength() { if (knownBitLength==null) { knownBitLength = CalcKnownBitLength(); } return FastInteger.Copy(knownBitLength); }
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; } } } }