Пример #1
0
 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;
       }
 }
Пример #2
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);
        }