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 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); }