Example #1
0
     public static void TestStringEqualRoundTrip(EInteger obj) {
   string str = obj.ToString();
   EInteger newobj = EInteger.FromString(str);
   string str2 = newobj.ToString();
   TestCommon.AssertEqualsHashCode(obj, newobj);
   TestCommon.AssertEqualsHashCode(str, str2);
 }
Example #2
0
 public CBORObject GetObject(EInteger bigIndex)
 {
     if (bigIndex.Sign < 0) {
     throw new CBORException("Unexpected index");
       }
       if (!bigIndex.CanFitInInt32()) {
     throw new CBORException("Index " + bigIndex +
             " is bigger than supported ");
       }
       var index = (int)bigIndex;
       if (index >= this.sharedObjects.Count) {
     throw new CBORException("Index " + index + " is not valid");
       }
       return this.sharedObjects[index];
 }
   public DigitShiftAccumulator(
 EInteger bigint,
 int lastDiscarded,
 int olderDiscarded) {
     if (bigint.CanFitInInt32()) {
       this.shiftedSmall = (int)bigint;
       if (this.shiftedSmall < 0) {
         throw new ArgumentException("shiftedSmall (" + this.shiftedSmall +
           ") is less than 0");
       }
       this.isSmall = true;
     } else {
       this.shiftedBigInt = bigint;
       this.isSmall = false;
     }
     this.bitsAfterLeftmost = (olderDiscarded != 0) ? 1 : 0;
     this.bitLeftmost = lastDiscarded;
   }
Example #4
0
    public EInteger[] FindCachedPowerIntOrSmaller(int precision) {
      EInteger[] ret = null;
      var integerMinValue = -1;
      lock (this.outputs) {
        for (var i = 0; i < this.size; ++i) {
          if (this.inputsInts[i] >= 0 &&
              this.inputsInts[i] <= precision && (integerMinValue == -1 ||
          this.inputsInts[i] >= integerMinValue)) {
 // DebugUtility.Log("Have cached power (" + inputs[i] + "," + bi + ") ");
            ret = new EInteger[2];
            ret[0] = this.inputs[i];
            ret[1] = this.outputs[i];
            integerMinValue = this.inputsInts[i];
          }
        }
      }
      return ret;
    }
Example #5
0
 internal static EInteger ShiftLeftInt(EInteger val, int shift) {
   #if DEBUG
   if (val == null) {
     throw new ArgumentNullException("val");
   }
   #endif
   if (val.IsZero) {
     return val;
   }
   while (shift > 1000000) {
     val <<= 1000000;
     shift -= 1000000;
   }
   var lastshift = (int)shift;
   val <<= lastshift;
   return val;
 }
Example #6
0
 public static string BigIntToString(EInteger bigint)
 {
     return bigint.ToString();
 }
Example #7
0
 public static void TestMultiplyDivideOne(
  EInteger bigintA,
  EInteger bigintB) {
   // Test that A*B/A = B and A*B/B = A
   try {
     EInteger bigintRem;
     EInteger bigintE;
     EInteger bigintD;
     EInteger bigintC = bigintA.Multiply (bigintB);
     TestCommon.CompareTestEqualAndConsistent (
       bigintC,
       bigintB.Multiply (bigintA));
     if (!bigintB.IsZero) {
       {
         EInteger [] divrem = bigintC.DivRem (bigintB);
         bigintD = divrem [0];
         bigintRem = divrem [1];
       }
       TestCommon.CompareTestEqualAndConsistent (bigintD, bigintA);
       TestCommon.CompareTestEqual (EInteger.Zero, bigintRem);
       bigintE = bigintC.Divide (bigintB);
       // Testing that DivRem and division method return
       // the same value
       TestCommon.CompareTestEqualAndConsistent (bigintD, bigintE);
       bigintE = bigintC.Remainder (bigintB);
       TestCommon.CompareTestEqualAndConsistent (bigintRem, bigintE);
       if (bigintE.Sign > 0 && !bigintC.Mod (bigintB).Equals (bigintE)) {
         TestCommon.CompareTestEqualAndConsistent (
           bigintE,
           bigintC.Mod (bigintB));
       }
     }
     if (!bigintA.IsZero) {
       EInteger [] divrem = bigintC.DivRem (bigintA);
       bigintD = divrem [0];
       bigintRem = divrem [1];
       TestCommon.CompareTestEqualAndConsistent (bigintD, bigintB);
       TestCommon.CompareTestEqual (EInteger.Zero, bigintRem);
     }
     if (!bigintB.IsZero) {
       EInteger [] divrem = bigintA.DivRem (bigintB);
       bigintC = divrem [0];
       bigintRem = divrem [1];
       bigintD = bigintB.Multiply (bigintC);
       bigintD += (EInteger)bigintRem;
       TestCommon.CompareTestEqualAndConsistent (bigintA, bigintD);
     }
     // -----------------------------------
     // EDecimal
     // -----------------------------------
     EDecimal edecA = EDecimal.FromEInteger (bigintA);
     EDecimal edecB = EDecimal.FromEInteger (bigintB);
     EDecimal edecC = edecA.Multiply (edecB);
     EDecimal edecRem;
     EDecimal edecE;
     EDecimal edecD;
     TestCommon.CompareTestEqualAndConsistent (
       edecC,
       edecB.Multiply (edecA));
     if (!edecB.IsZero) {
       EDecimal [] divrem = edecC.DivRemNaturalScale (edecB);
       edecD = divrem [0].Plus (null);
       edecRem = divrem [1];
       TestCommon.CompareTestEqualAndConsistent (edecD, edecA);
       TestCommon.CompareTestEqual (EDecimal.Zero, edecRem);
       edecE = edecC.DivideToExponent (edecB, 0, ERounding.Down);
       // Testing that DivRemNaturalScale and division method return
       // the same value
       TestCommon.CompareTestEqualAndConsistent (edecD, edecE);
       edecE = edecC.RemainderNaturalScale (edecB, null);
       TestCommon.CompareTestEqualAndConsistent (edecRem, edecE);
     }
     if (!edecA.IsZero) {
       EDecimal [] divrem = edecC.DivRemNaturalScale (edecA);
       edecD = divrem [0].Plus (null);
       edecRem = divrem [1];
       TestCommon.CompareTestEqualAndConsistent (edecD, edecB);
       TestCommon.CompareTestEqual (EDecimal.Zero, edecRem);
     }
     if (!edecB.IsZero) {
       EDecimal [] divrem = edecA.DivRemNaturalScale (edecB);
       edecC = divrem [0].Plus (null);
       edecRem = divrem [1];
       edecD = edecB.Multiply (edecC);
       edecD = edecD.Add (edecRem);
       TestCommon.CompareTestEqualAndConsistent (edecA, edecD);
     }
     // -----------------------------------
     // EFloat
     // -----------------------------------
     EFloat efloatA = EFloat.FromEInteger (bigintA);
     EFloat efloatB = EFloat.FromEInteger (bigintB);
     EFloat efloatC = efloatA.Multiply (efloatB);
     EFloat efloatRem;
     EFloat efloatE;
     EFloat efloatD;
     TestCommon.CompareTestEqualAndConsistent (
       efloatC,
       efloatB.Multiply (efloatA));
     if (!efloatB.IsZero) {
       EFloat [] divrem = efloatC.DivRemNaturalScale (efloatB);
       efloatD = divrem [0].Plus (null);
       efloatRem = divrem [1];
       TestCommon.CompareTestEqualAndConsistent (efloatD, efloatA);
       TestCommon.CompareTestEqual (EFloat.Zero, efloatRem);
       efloatE = efloatC.DivideToExponent (efloatB, 0, ERounding.Down);
       // Testing that DivRemNaturalScale and division method return
       // the same value
       TestCommon.CompareTestEqualAndConsistent (efloatD, efloatE);
       efloatE = efloatC.RemainderNaturalScale (efloatB, null);
       TestCommon.CompareTestEqualAndConsistent (efloatRem, efloatE);
     }
     if (!efloatA.IsZero) {
       EFloat [] divrem = efloatC.DivRemNaturalScale (efloatA);
       efloatD = divrem [0].Plus (null);
       efloatRem = divrem [1];
       TestCommon.CompareTestEqualAndConsistent (efloatD, efloatB);
       TestCommon.CompareTestEqual (EFloat.Zero, efloatRem);
     }
     if (!efloatB.IsZero) {
       EFloat [] divrem = efloatA.DivRemNaturalScale (efloatB);
       efloatC = divrem [0].Plus (null);
       efloatRem = divrem [1];
       efloatD = efloatB.Multiply (efloatC);
       efloatD = efloatD.Add (efloatRem);
       TestCommon.CompareTestEqualAndConsistent (efloatA, efloatD);
     }
   } catch (Exception ex) {
 string testLine =
       "TestMultiplyDivideOne (\nEInteger.FromRadixString (\"" +
       bigintA.ToRadixString (16) + "\",16),\nEInteger.FromRadixString (\"" +
             bigintB.ToRadixString (16) + "\",16));";
     Console.WriteLine(testLine);
     throw new InvalidOperationException(ex.Message + "\n"+testLine,ex);
   }
 }
Example #8
0
 public static void AssertBigIntegersEqual(string a, EInteger b) {
   Assert.AreEqual(a, b.ToString());
   EInteger a2 = BigFromString(a);
   TestCommon.CompareTestEqualAndConsistent(a2, b);
   TestCommon.AssertEqualsHashCode(a2, b);
 }
Example #9
0
   /// <include file='../../docs.xml'
   /// path='docs/doc[@name="M:PeterO.Numbers.EContext.#ctor(System.Int32,PeterO.Numbers.ERounding,System.Int32,System.Int32,System.Boolean)"]/*'/>
   public EContext(
 int precision,
 ERounding rounding,
 int exponentMinSmall,
 int exponentMaxSmall,
 bool clampNormalExponents) {
     if (precision < 0) {
       throw new ArgumentException("precision (" + precision +
         ") is less than 0");
     }
     if (exponentMinSmall > exponentMaxSmall) {
       throw new ArgumentException("exponentMinSmall (" + exponentMinSmall +
         ") is more than " + exponentMaxSmall);
     }
     this.bigintPrecision = precision == 0 ? EInteger.Zero :
       (EInteger)precision;
     this.rounding = rounding;
     this.clampNormalExponents = clampNormalExponents;
     this.hasExponentRange = true;
     this.adjustExponent = true;
     this.exponentMax = exponentMaxSmall == 0 ? EInteger.Zero :
       (EInteger)exponentMaxSmall;
     this.exponentMin = exponentMinSmall == 0 ? EInteger.Zero :
       (EInteger)exponentMinSmall;
   }
Example #10
0
 public static ERational FromUInt64(ulong inputUInt64)
 {
     return(FromEInteger(EInteger.FromUInt64(inputUInt64)));
 }
Example #11
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);
             this.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);
                 this.VerifyKnownLength();
                 return;
             }
             else
             {
                 // NOTE: For BitShiftAccumulator, truncating and shifting
                 // are the same, unlike in DigitShiftAccumulator
                 this.ShiftRight(bitDiff);
                 this.VerifyKnownLength();
                 return;
             }
         }
     }
     if (bits.CanFitInInt32())
     {
         this.ShiftToDigitsInt(bits.AsInt32());
         this.VerifyKnownLength();
     }
     else
     {
         this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength();
         EInteger bigintDiff = this.knownBitLength.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 #12
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.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;
             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;
             }
             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;
     }
 }
Example #13
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;
                    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;
                    }
                    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;
            }
        }
Example #14
0
        internal FastInteger Add(FastInteger val)
        {
            this.CheckFrozen();
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if (val.integerMode == 0)
                {
                    if ((this.smallValue < 0 && (int)val.smallValue < Int32.MinValue
                         - this.smallValue) ||
                        (this.smallValue > 0 && (int)val.smallValue > Int32.MaxValue
                         - this.smallValue))
                    {
                        // would overflow
                        if (val.smallValue >= 0)
                        {
                            this.integerMode = 1;
                            this.mnum        = new MutableNumber(this.smallValue);
                            this.mnum.Add(val.smallValue);
                        }
                        else
                        {
                            this.integerMode = 2;
                            this.largeValue  = (EInteger)this.smallValue;
                            this.largeValue += (EInteger)val.smallValue;
                        }
                    }
                    else
                    {
                        this.smallValue += val.smallValue;
                    }
                }
                else
                {
                    integerMode = 2;
                    largeValue  = (EInteger)smallValue;
                    valValue    = val.AsEInteger();
                    largeValue += (EInteger)valValue;
                }
                break;

            case 1:
                if (val.integerMode == 0 && val.smallValue >= 0)
                {
                    this.mnum.Add(val.smallValue);
                }
                else
                {
                    integerMode = 2;
                    largeValue  = mnum.ToEInteger();
                    valValue    = val.AsEInteger();
                    largeValue += (EInteger)valValue;
                }
                break;

            case 2:
                valValue         = val.AsEInteger();
                this.largeValue += (EInteger)valValue;
                break;

            default: throw new InvalidOperationException();
            }
            return(this);
        }
Example #15
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Subtract(PeterO.Numbers.FastInteger)"]/*'/>
        internal FastInteger Subtract(FastInteger val)
        {
            this.CheckFrozen();
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if (val.integerMode == 0)
                {
                    int vsv = val.smallValue;
                    if ((vsv < 0 && Int32.MaxValue + vsv < this.smallValue) ||
                        (vsv > 0 && Int32.MinValue + vsv > this.smallValue))
                    {
                        // would overflow, convert to large
                        this.integerMode = 2;
                        this.largeValue  = (EInteger)this.smallValue;
                        this.largeValue -= (EInteger)vsv;
                    }
                    else
                    {
                        this.smallValue -= vsv;
                    }
                }
                else
                {
                    integerMode = 2;
                    largeValue  = (EInteger)smallValue;
                    valValue    = val.AsEInteger();
                    largeValue -= (EInteger)valValue;
                }
                break;

            case 1:
                if (val.integerMode == 1)
                {
                    // NOTE: Mutable numbers are
                    // currently always zero or positive
                    this.mnum.Subtract(val.mnum);
                }
                else if (val.integerMode == 0 && val.smallValue >= 0)
                {
                    mnum.SubtractInt(val.smallValue);
                }
                else
                {
                    integerMode = 2;
                    largeValue  = mnum.ToEInteger();
                    valValue    = val.AsEInteger();
                    largeValue -= (EInteger)valValue;
                }
                break;

            case 2:
                valValue         = val.AsEInteger();
                this.largeValue -= (EInteger)valValue;
                break;

            default: throw new InvalidOperationException();
            }
            return(this);
        }
Example #16
0
 public void AddPower(EInteger input, EInteger output) {
   lock (this.outputs) {
     if (this.size < MaxSize) {
       // Shift newer entries down
       for (int i = this.size; i > 0; --i) {
         this.inputs[i] = this.inputs[i - 1];
         this.inputsInts[i] = this.inputsInts[i - 1];
         this.outputs[i] = this.outputs[i - 1];
       }
       this.inputs[0] = input;
  this.inputsInts[0] = input.CanFitInInt32() ? input.ToInt32Checked() : -1;
       this.outputs[0] = output;
       ++this.size;
     } else {
       // Shift newer entries down
       for (int i = MaxSize - 1; i > 0; --i) {
         this.inputs[i] = this.inputs[i - 1];
         this.inputsInts[i] = this.inputsInts[i - 1];
         this.outputs[i] = this.outputs[i - 1];
       }
       this.inputs[0] = input;
  this.inputsInts[0] = input.CanFitInInt32() ? input.ToInt32Checked() : -1;
       this.outputs[0] = output;
     }
   }
 }
Example #17
0
 internal static EInteger FindPowerOfTenFromBig(EInteger
 bigintExponent) {
   int sign = bigintExponent.Sign;
   if (sign < 0) {
     return EInteger.Zero;
   }
   if (sign == 0) {
     return EInteger.One;
   }
   if (bigintExponent.CompareTo(ValueBigInt36) <= 0) {
     return FindPowerOfTen((int)bigintExponent);
   }
   FastInteger intcurexp = FastInteger.FromBig(bigintExponent);
   EInteger mantissa = EInteger.One;
   EInteger bigpow = EInteger.Zero;
   while (intcurexp.Sign > 0) {
     if (intcurexp.CompareToInt(18) <= 0) {
       bigpow = FindPowerOfTen(intcurexp.AsInt32());
       mantissa *= (EInteger)bigpow;
       break;
     }
     if (intcurexp.CompareToInt(9999999) <= 0) {
       int val = intcurexp.AsInt32();
       bigpow = FindPowerOfFive(val);
       bigpow <<= val;
       mantissa *= (EInteger)bigpow;
       break;
     }
     if (bigpow.IsZero) {
       bigpow = FindPowerOfFive(9999999);
       bigpow <<= 9999999;
     }
     mantissa *= bigpow;
     intcurexp.AddInt(-9999999);
   }
   return mantissa;
 }
Example #18
0
 private static EInteger FromRadixSubstringGeneral(
     string cs,
     int radix,
     int index,
     int endIndex,
     bool negative,
     bool throwException)
 {
     if (endIndex - index > 72)
     {
         int      midIndex = index + ((endIndex - index) / 2);
         EInteger eia      = FromRadixSubstringGeneral(
             cs,
             radix,
             index,
             midIndex,
             false,
             throwException);
         // DebugUtility.Log("eia="+eia);
         EInteger eib = FromRadixSubstringGeneral(
             cs,
             radix,
             midIndex,
             endIndex,
             false,
             throwException);
         // DebugUtility.Log("eib="+eib);
         EInteger mult   = null;
         int      intpow = endIndex - midIndex;
         if (radix == 10)
         {
             eia = NumberUtility.MultiplyByPowerOfFive(eia,
                                                       intpow).ShiftLeft(intpow);
         }
         else if (radix == 5)
         {
             eia = NumberUtility.MultiplyByPowerOfFive(eia, intpow);
         }
         else
         {
             mult = EInteger.FromInt32(radix).Pow(endIndex - midIndex);
             eia  = eia.Multiply(mult);
         }
         eia = eia.Add(eib);
         // DebugUtility.Log("index={0} {1} {2} [pow={3}] [pow={4} ms, muladd={5} ms]",
         // index, midIndex, endIndex, endIndex-midIndex, swPow.ElapsedMilliseconds,
         // swMulAdd.ElapsedMilliseconds);
         if (negative)
         {
             eia = eia.Negate();
         }
         // DebugUtility.Log("eia now="+eia);
         return(eia);
     }
     else
     {
         return(FromRadixSubstringInner(
                    cs,
                    radix,
                    index,
                    endIndex,
                    negative,
                    throwException));
     }
 }
Example #19
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Numbers.EContext.WithBigExponentRange(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/>
 public EContext WithBigExponentRange(
   EInteger exponentMin,
   EInteger exponentMax) {
   if (exponentMin == null) {
     throw new ArgumentNullException("exponentMin");
   }
   if (exponentMax == null) {
     throw new ArgumentNullException("exponentMax");
   }
   if (exponentMin.CompareTo(exponentMax) > 0) {
     throw new ArgumentException("exponentMin greater than exponentMax");
   }
   EContext pc = this.Copy();
   pc.hasExponentRange = true;
   pc.exponentMin = exponentMin;
   pc.exponentMax = exponentMax;
   return pc;
 }
Example #20
0
        private static EInteger FromRadixSubstringInner(
            string cs,
            int radix,
            int index,
            int endIndex,
            bool negative,
            bool throwException)
        {
            if (radix <= 10)
            {
                long rv         = 0;
                var  digitCount = 0;
                if (radix == 10)
                {
                    for (int i = index; i < endIndex; ++i)
                    {
                        char c     = cs[i];
                        var  digit = (int)c - 0x30;
                        if (digit >= radix || digit < 0)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        if (digitCount < 0 || digitCount >= 18)
                        {
                            digitCount = -1;
                            break;
                        }
                        else if (digitCount > 0 || digit != 0)
                        {
                            ++digitCount;
                        }
                        rv = (rv * 10) + digit;
                    }
                    // DebugUtility.Log("short="+(negative ? -rv : rv));
                    if (digitCount >= 0)
                    {
                        return(EInteger.FromInt64(negative ? -rv : rv));
                    }
                }
                else
                {
                    for (int i = index; i < endIndex; ++i)
                    {
                        char c     = cs[i];
                        int  digit = (c >= 0x80) ? 36 : ((int)c - 0x30);
                        if (digit >= radix || digit < 0)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        if (digitCount < 0 || digitCount >= 18)
                        {
                            digitCount = -1;
                            break;
                        }
                        else if (digitCount > 0 || digit != 0)
                        {
                            ++digitCount;
                        }
                        rv = (rv * radix) + digit;
                    }
                    if (digitCount >= 0)
                    {
                        return(EInteger.FromInt64(negative ? -rv : rv));
                    }
                }
            }
            int[] c2d   = EInteger.CharToDigit;
            int[] d2w   = EInteger.DigitsInWord;
            long  lsize = ((long)(endIndex - index) * 100 / d2w[radix]) + 1;

            lsize = Math.Min(lsize, Int32.MaxValue);
            lsize = Math.Max(lsize, 5);
            var bigint = new short[(int)lsize];

            if (radix == 10)
            {
                long rv = 0;
                int  ei = endIndex - index <= 18 ? endIndex : index + 18;
                for (int i = index; i < ei; ++i)
                {
                    char c     = cs[i];
                    var  digit = (int)c - 0x30;
                    if (digit >= radix || digit < 0)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }
                    rv = (rv * 10) + digit;
                }
                bigint[0] = unchecked ((short)(rv & ShortMask));
                bigint[1] = unchecked ((short)((rv >> 16) & ShortMask));
                bigint[2] = unchecked ((short)((rv >> 32) & ShortMask));
                bigint[3] = unchecked ((short)((rv >> 48) & ShortMask));
                int bn = Math.Min(bigint.Length, 5);
                for (int i = ei; i < endIndex; ++i)
                {
                    short carry = 0;
                    var   digit = 0;
                    var   overf = 0;
                    if (i < endIndex - 3)
                    {
                        overf = 55536; // 2**16 minus 10**4
                        var d1 = (int)cs[i] - 0x30;
                        var d2 = (int)cs[i + 1] - 0x30;
                        var d3 = (int)cs[i + 2] - 0x30;
                        var d4 = (int)cs[i + 3] - 0x30;
                        i += 3;
                        if (d1 >= 10 || d1 < 0 || d2 >= 10 || d2 < 0 || d3 >= 10 ||
                            d3 < 0 || d4 >= 10 || d4 < 0)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        digit = (d1 * 1000) + (d2 * 100) + (d3 * 10) + d4;
                        // Multiply by 10**4
                        for (int j = 0; j < bn; ++j)
                        {
                            int p;
                            p = unchecked ((((int)bigint[j]) & ShortMask) *
                                           10000);
                            int p2 = ((int)carry) & ShortMask;
                            p         = unchecked (p + p2);
                            bigint[j] = unchecked ((short)p);
                            carry     = unchecked ((short)(p >> 16));
                        }
                    }
                    else
                    {
                        overf = 65526; // 2**16 minus radix 10
                        char c = cs[i];
                        digit = (int)c - 0x30;
                        if (digit >= 10 || digit < 0)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        // Multiply by 10
                        for (int j = 0; j < bn; ++j)
                        {
                            int p;
                            p = unchecked ((((int)bigint[j]) & ShortMask) * 10);
                            int p2 = ((int)carry) & ShortMask;
                            p         = unchecked (p + p2);
                            bigint[j] = unchecked ((short)p);
                            carry     = unchecked ((short)(p >> 16));
                        }
                    }
                    if (carry != 0)
                    {
                        bigint = EInteger.GrowForCarry(bigint, carry);
                    }
                    // Add the parsed digit
                    if (digit != 0)
                    {
                        int d = bigint[0] & ShortMask;
                        if (d <= overf)
                        {
                            bigint[0] = unchecked ((short)(d + digit));
                        }
                        else if (EInteger.IncrementWords(
                                     bigint,
                                     0,
                                     bigint.Length,
                                     (short)digit) != 0)
                        {
                            bigint = EInteger.GrowForCarry(bigint, (short)1);
                        }
                    }
                    bn = Math.Min(bigint.Length, bn + 1);
                }
            }
            else
            {
                var   haveSmallInt = true;
                int[] msi          = EInteger.MaxSafeInts;
                int   maxSafeInt   = msi[radix - 2];
                int   maxShortPlusOneMinusRadix = 65536 - radix;
                var   smallInt = 0;
                for (int i = index; i < endIndex; ++i)
                {
                    char c     = cs[i];
                    int  digit = (c >= 0x80) ? 36 : c2d[(int)c];
                    if (digit >= radix)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }
                    if (haveSmallInt && smallInt < maxSafeInt)
                    {
                        smallInt = (smallInt * radix) + digit;
                    }
                    else
                    {
                        if (haveSmallInt)
                        {
                            bigint[0] = unchecked ((short)(smallInt &
                                                           ShortMask));
                            bigint[1] = unchecked ((short)((smallInt >> 16) &
                                                           ShortMask));
                            haveSmallInt = false;
                        }
                        // Multiply by the radix
                        short carry = 0;
                        int   n     = bigint.Length;
                        for (int j = 0; j < n; ++j)
                        {
                            int p;
                            p = unchecked ((((int)bigint[j]) & ShortMask) *
                                           radix);
                            int p2 = ((int)carry) & ShortMask;
                            p         = unchecked (p + p2);
                            bigint[j] = unchecked ((short)p);
                            carry     = unchecked ((short)(p >> 16));
                        }
                        if (carry != 0)
                        {
                            bigint = EInteger.GrowForCarry(bigint, carry);
                        }
                        // Add the parsed digit
                        if (digit != 0)
                        {
                            int d = bigint[0] & ShortMask;
                            if (d <= maxShortPlusOneMinusRadix)
                            {
                                bigint[0] = unchecked ((short)(d + digit));
                            }
                            else if (EInteger.IncrementWords(
                                         bigint,
                                         0,
                                         bigint.Length,
                                         (short)digit) != 0)
                            {
                                bigint = EInteger.GrowForCarry(bigint, (short)1);
                            }
                        }
                    }
                }
                if (haveSmallInt)
                {
                    bigint[0] = unchecked ((short)(smallInt & ShortMask));
                    bigint[1] = unchecked ((short)((smallInt >> 16) &
                                                   ShortMask));
                }
            }
            int count = EInteger.CountWords(bigint);

            return((count == 0) ? EInteger.Zero : new EInteger(
                       count,
                       bigint,
                       negative));
        }
Example #21
0
 public static void DoTestShiftRight2(string m1, int m2, EInteger result) {
   EInteger bigintA = BigFromString(m1);
   TestCommon.CompareTestEqualAndConsistent(result, bigintA >> m2);
   m2 = -m2;
   TestCommon.CompareTestEqualAndConsistent(result, bigintA << m2);
 }
Example #22
0
        public static EInteger FromRadixSubstringImpl(
            string cs,
            int radix,
            int index,
            int endIndex,
            bool throwException)
        {
            if (radix < 2)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("radix(" + radix + ") is less than 2");
                }
            }
            if (radix > 36)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("radix(" + radix + ") is more than 36");
                }
            }
            if (index < 0)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("index(" + index + ") is less than " + "0");
                }
            }
            if (index > cs.Length)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("index(" + index + ") is more than " + cs.Length);
                }
            }
            if (endIndex < 0)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("endIndex(" + endIndex + ") is less than 0");
                }
            }
            if (endIndex > cs.Length)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("endIndex(" + endIndex + ") is more than " +
                                                cs.Length);
                }
            }
            if (endIndex < index)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentException("endIndex(" + endIndex + ") is less than " +
                                                index);
                }
            }
            if (index == endIndex)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new FormatException("No digits");
                }
            }
            var negative = false;

            if (cs[index] == '-')
            {
                ++index;
                if (index == endIndex)
                {
                    if (!throwException)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new FormatException("No digits");
                    }
                }
                negative = true;
            }
            // Skip leading zeros
            for (; index < endIndex; ++index)
            {
                char c = cs[index];
                if (c != 0x30)
                {
                    break;
                }
            }
            int effectiveLength = endIndex - index;

            if (effectiveLength == 0)
            {
                return(EInteger.Zero);
            }
            int[]   c2d = EInteger.CharToDigit;
            short[] bigint;
            if (radix == 16)
            {
                // Special case for hexadecimal radix
                int leftover  = effectiveLength & 3;
                int wordCount = effectiveLength >> 2;
                if (leftover != 0)
                {
                    ++wordCount;
                }
                bigint = new short[wordCount];
                int currentDigit = wordCount - 1;
                // Get most significant digits if effective
                // length is not divisible by 4
                if (leftover != 0)
                {
                    var extraWord = 0;
                    for (int i = 0; i < leftover; ++i)
                    {
                        extraWord <<= 4;
                        char c     = cs[index + i];
                        int  digit = (c >= 0x80) ? 36 : c2d[(int)c];
                        if (digit >= 16)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        extraWord |= digit;
                    }
                    bigint[currentDigit] = unchecked ((short)extraWord);
                    --currentDigit;
                    index += leftover;
                }
        #if DEBUG
                if ((endIndex - index) % 4 != 0)
                {
                    if (!throwException)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new InvalidOperationException("doesn't satisfy (endIndex - index) %" +
                                                            "\u00204 == 0");
                    }
                }
        #endif
                while (index < endIndex)
                {
                    char c     = cs[index + 3];
                    int  digit = (c >= 0x80) ? 36 : c2d[(int)c];
                    if (digit >= 16)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }
                    int word = digit;
                    c     = cs[index + 2];
                    digit = (c >= 0x80) ? 36 : c2d[(int)c];
                    if (digit >= 16)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }

                    word |= digit << 4;
                    c     = cs[index + 1];
                    digit = (c >= 0x80) ? 36 : c2d[(int)c];
                    if (digit >= 16)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }

                    word |= digit << 8;
                    c     = cs[index];
                    digit = (c >= 0x80) ? 36 : c2d[(int)c];
                    if (digit >= 16)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException("Illegal character found");
                        }
                    }
                    word  |= digit << 12;
                    index += 4;
                    bigint[currentDigit] = unchecked ((short)word);
                    --currentDigit;
                }
                int count = EInteger.CountWords(bigint);
                return((count == 0) ? EInteger.Zero : new EInteger(
                           count,
                           bigint,
                           negative));
            }
            else if (radix == 2)
            {
                // Special case for binary radix
                int leftover  = effectiveLength & 15;
                int wordCount = effectiveLength >> 4;
                if (leftover != 0)
                {
                    ++wordCount;
                }
                bigint = new short[wordCount];
                int currentDigit = wordCount - 1;
                // Get most significant digits if effective
                // length is not divisible by 4
                if (leftover != 0)
                {
                    var extraWord = 0;
                    for (int i = 0; i < leftover; ++i)
                    {
                        extraWord <<= 1;
                        char c     = cs[index + i];
                        int  digit = (c == '0') ? 0 : ((c == '1') ? 1 : 2);
                        if (digit >= 2)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        extraWord |= digit;
                    }
                    bigint[currentDigit] = unchecked ((short)extraWord);
                    --currentDigit;
                    index += leftover;
                }
                while (index < endIndex)
                {
                    var word = 0;
                    int idx  = index + 15;
                    for (var i = 0; i < 16; ++i)
                    {
                        char c     = cs[idx];
                        int  digit = (c == '0') ? 0 : ((c == '1') ? 1 : 2);
                        if (digit >= 2)
                        {
                            if (!throwException)
                            {
                                return(null);
                            }
                            else
                            {
                                throw new FormatException("Illegal character found");
                            }
                        }
                        --idx;
                        word |= digit << i;
                    }
                    index += 16;
                    bigint[currentDigit] = unchecked ((short)word);
                    --currentDigit;
                }
                int count = EInteger.CountWords(bigint);
                return((count == 0) ? EInteger.Zero : new EInteger(
                           count,
                           bigint,
                           negative));
            }
            else
            {
                return(FromRadixSubstringGeneral(
                           cs,
                           radix,
                           index,
                           endIndex,
                           negative,
                           throwException));
            }
        }
Example #23
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Multiply(System.Int32)"]/*'/>
        internal FastInteger Multiply(int val)
        {
            this.CheckFrozen();
            if (val == 0)
            {
                this.smallValue  = 0;
                this.integerMode = 0;
            }
            else
            {
                switch (this.integerMode)
                {
                case 0: {
                    long amult = ((long)val) * ((long)this.smallValue);
                    if (amult > Int32.MaxValue || amult < Int32.MinValue)
                    {
                        // would overflow, convert to large
                        bool apos = this.smallValue > 0L;
                        bool bpos = val > 0L;
                        if (apos && bpos)
                        {
                            // if both operands are nonnegative
                            // convert to mutable big integer
                            this.integerMode = 1;
                            this.mnum        = MutableNumber.FromLong(amult);
                        }
                        else
                        {
                            // if either operand is negative
                            // convert to big integer
                            this.integerMode = 2;
                            this.largeValue  = EInteger.FromInt64(amult);
                        }
                    }
                    else
                    {
                        this.smallValue = unchecked ((int)amult);
                    }
                    break;
                }

                case 1:
                    if (val < 0)
                    {
                        this.integerMode = 2;
                        this.largeValue  = this.mnum.ToEInteger();
                        this.largeValue *= (EInteger)val;
                    }
                    else
                    {
                        mnum.Multiply(val);
                    }
                    break;

                case 2:
                    this.largeValue *= (EInteger)val;
                    break;

                default: throw new InvalidOperationException();
                }
            }
            return(this);
        }
Example #24
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.Equals(PeterO.Numbers.EInteger)"]/*'/>
 public bool Equals(EInteger other)
 {
     return((other != null) && (this.CompareTo(other) == 0));
 }
Example #25
0
 public CBORObject GetString(EInteger bigIndex)
 {
     if (bigIndex.Sign < 0) {
     throw new CBORException("Unexpected index");
       }
       if (!bigIndex.CanFitInInt32()) {
     throw new CBORException("Index " + bigIndex +
       " is bigger than supported ");
       }
       var index = (int)bigIndex;
       List<CBORObject> lastList = this.stack[this.stack.Count - 1];
       if (index >= lastList.Count) {
     throw new CBORException("Index " + index + " is not valid");
       }
       CBORObject ret = lastList[index];
       // Byte strings are mutable, so make a copy
       return (ret.Type == CBORType.ByteString) ?
     CBORObject.FromObject(ret.GetByteString()) : ret;
 }
Example #26
0
 internal static FastIntegerFixed FromBig(EInteger bigintVal)
 {
     return(bigintVal.CanFitInInt32() ?
            FromInt32(bigintVal.ToInt32Unchecked()) : new
            FastIntegerFixed(IntegerMode.LargeValue, 0, bigintVal));
 }
Example #27
0
 internal static EInteger ShiftLeft(EInteger val, EInteger bigShift) {
   #if DEBUG
   if (val == null) {
     throw new ArgumentNullException("val");
   }
   if (bigShift == null) {
     throw new ArgumentNullException("bigShift");
   }
   #endif
   if (val.IsZero) {
     return val;
   }
   while (bigShift.CompareTo(ValueBigShiftIteration) > 0) {
     val <<= 1000000;
     bigShift -= (EInteger)ValueBigShiftIteration;
   }
   var lastshift = (int)bigShift;
   val <<= lastshift;
   return val;
 }
Example #28
0
        internal static EFloat DoubleEFloatFromString(
            char[] chars,
            int offset,
            int length,
            EContext ctx,
            bool throwException)
        {
            int tmpoffset = offset;

            if (chars == null)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new ArgumentNullException(nameof(chars));
                }
            }
            if (length == 0)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new FormatException();
                }
            }
            int  endStr           = tmpoffset + length;
            var  negative         = false;
            var  haveDecimalPoint = false;
            var  haveDigits       = false;
            var  haveExponent     = false;
            var  newScaleInt      = 0;
            var  digitStart       = 0;
            int  i            = tmpoffset;
            long mantissaLong = 0L;

            // Ordinary number
            if (chars[i] == '+' || chars[i] == '-')
            {
                if (chars[i] == '-')
                {
                    negative = true;
                }
                ++i;
            }
            digitStart = i;
            int digitEnd          = i;
            int decimalDigitStart = i;
            var haveNonzeroDigit  = false;
            var decimalPrec       = 0;
            int decimalDigitEnd   = i;
            var nonzeroBeyondMax  = false;
            var lastdigit         = -1;
            // 768 is maximum precision of a decimal
            // half-ULP in double format
            var maxDecimalPrec = 768;

            if (length > 21)
            {
                int eminInt = ctx.EMin.ToInt32Checked();
                int emaxInt = ctx.EMax.ToInt32Checked();
                int precInt = ctx.Precision.ToInt32Checked();
                if (eminInt >= -14 && emaxInt <= 15)
                {
                    maxDecimalPrec = (precInt <= 11) ? 21 : 63;
                }
                else if (eminInt >= -126 && emaxInt <= 127)
                {
                    maxDecimalPrec = (precInt <= 24) ? 113 : 142;
                }
            }
            for (; i < endStr; ++i)
            {
                char ch = chars[i];
                if (ch >= '0' && ch <= '9')
                {
                    var thisdigit = (int)(ch - '0');
                    haveDigits        = true;
                    haveNonzeroDigit |= thisdigit != 0;
                    if (decimalPrec > maxDecimalPrec)
                    {
                        if (thisdigit != 0)
                        {
                            nonzeroBeyondMax = true;
                        }
                        if (!haveDecimalPoint)
                        {
                            // NOTE: Absolute value will not be more than
                            // the char[] portion's length, so will fit comfortably
                            // in an 'int'.
                            newScaleInt = checked (newScaleInt + 1);
                        }
                        continue;
                    }
                    lastdigit = thisdigit;
                    if (haveNonzeroDigit)
                    {
                        ++decimalPrec;
                    }
                    if (haveDecimalPoint)
                    {
                        decimalDigitEnd = i + 1;
                    }
                    else
                    {
                        digitEnd = i + 1;
                    }
                    if (mantissaLong <= 922337203685477580L)
                    {
                        mantissaLong *= 10;
                        mantissaLong += thisdigit;
                    }
                    else
                    {
                        mantissaLong = Int64.MaxValue;
                    }
                    if (haveDecimalPoint)
                    {
                        // NOTE: Absolute value will not be more than
                        // the portion's length, so will fit comfortably
                        // in an 'int'.
                        newScaleInt = checked (newScaleInt - 1);
                    }
                }
                else if (ch == '.')
                {
                    if (haveDecimalPoint)
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException();
                        }
                    }
                    haveDecimalPoint  = true;
                    decimalDigitStart = i + 1;
                    decimalDigitEnd   = i + 1;
                }
                else if (ch == 'E' || ch == 'e')
                {
                    haveExponent = true;
                    ++i;
                    break;
                }
                else
                {
                    if (!throwException)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }
            }
            if (!haveDigits)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new FormatException();
                }
            }
            var  expInt        = 0;
            var  expoffset     = 1;
            var  expDigitStart = -1;
            var  expPrec       = 0;
            bool zeroMantissa  = !haveNonzeroDigit;

            haveNonzeroDigit = false;
            EFloat ef1, ef2;

            if (haveExponent)
            {
                haveDigits = false;
                if (i == endStr)
                {
                    if (!throwException)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }
                char ch = chars[i];
                if (ch == '+' || ch == '-')
                {
                    if (ch == '-')
                    {
                        expoffset = -1;
                    }
                    ++i;
                }
                expDigitStart = i;
                for (; i < endStr; ++i)
                {
                    ch = chars[i];
                    if (ch >= '0' && ch <= '9')
                    {
                        haveDigits = true;
                        var thisdigit = (int)(ch - '0');
                        haveNonzeroDigit |= thisdigit != 0;
                        if (haveNonzeroDigit)
                        {
                            ++expPrec;
                        }
                        if (expInt <= 214748364)
                        {
                            expInt *= 10;
                            expInt += thisdigit;
                        }
                        else
                        {
                            expInt = Int32.MaxValue;
                        }
                    }
                    else
                    {
                        if (!throwException)
                        {
                            return(null);
                        }
                        else
                        {
                            throw new FormatException();
                        }
                    }
                }
                if (!haveDigits)
                {
                    if (!throwException)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }
                expInt *= expoffset;
                if (expPrec > 12)
                {
                    // Exponent that can't be compensated by digit
                    // length without remaining beyond Int32 range
                    if (expoffset < 0)
                    {
                        return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa));
                    }
                    else
                    {
                        return(EFloat.SignalOverflow(ctx, negative, zeroMantissa));
                    }
                }
            }
            if (i != endStr)
            {
                if (!throwException)
                {
                    return(null);
                }
                else
                {
                    throw new FormatException();
                }
            }
            if (expInt != Int32.MaxValue && expInt > -Int32.MaxValue &&
                mantissaLong != Int64.MaxValue && (ctx == null ||
                                                   !ctx.HasFlagsOrTraps))
            {
                if (mantissaLong == 0)
                {
                    EFloat ef = EFloat.Create(
                        EInteger.Zero,
                        EInteger.FromInt32(expInt));
                    if (negative)
                    {
                        ef = ef.Negate();
                    }
                    return(ef.RoundToPrecision(ctx));
                }
                var  finalexp = (long)expInt + (long)newScaleInt;
                long ml       = mantissaLong;
                if (finalexp >= -22 && finalexp <= 44)
                {
                    var iexp = (int)finalexp;
                    while (ml <= 900719925474099L && iexp > 22)
                    {
                        ml *= 10;
                        --iexp;
                    }
                    int iabsexp = Math.Abs(iexp);
                    if (ml < 9007199254740992L && iabsexp == 0)
                    {
                        return(EFloat.FromInt64(negative ?
                                                -mantissaLong : mantissaLong).RoundToPrecision(ctx));
                    }
                    else if (ml < 9007199254740992L && iabsexp <= 22)
                    {
                        EFloat efn =
                            EFloat.FromEInteger(NumberUtility.FindPowerOfTen(iabsexp));
                        if (negative)
                        {
                            ml = -ml;
                        }
                        EFloat efml = EFloat.FromInt64(ml);
                        if (iexp < 0)
                        {
                            return(efml.Divide(efn, ctx));
                        }
                        else
                        {
                            return(efml.Multiply(efn, ctx));
                        }
                    }
                }
                long adjexpUpperBound = finalexp + (decimalPrec - 1);
                long adjexpLowerBound = finalexp;
                if (adjexpUpperBound < -326)
                {
                    return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa));
                }
                else if (adjexpLowerBound > 309)
                {
                    return(EFloat.SignalOverflow(ctx, negative, zeroMantissa));
                }
                if (negative)
                {
                    mantissaLong = -mantissaLong;
                }
                long absfinalexp = Math.Abs(finalexp);
                ef1 = EFloat.Create(mantissaLong, (int)0);
                ef2 = EFloat.FromEInteger(NumberUtility.FindPowerOfTen(absfinalexp));
                if (finalexp < 0)
                {
                    EFloat efret = ef1.Divide(ef2, ctx);

                    /* Console.WriteLine("div " + ef1 + "/" + ef2 + " -> " + (efret));
                     */return(efret);
                }
                else
                {
                    return(ef1.Multiply(ef2, ctx));
                }
            }
            EInteger mant = null;
            EInteger exp  = (!haveExponent) ? EInteger.Zero :
                            EInteger.FromSubstring(chars, expDigitStart, endStr);

            if (expoffset < 0)
            {
                exp = exp.Negate();
            }
            exp = exp.Add(newScaleInt);
            if (nonzeroBeyondMax)
            {
                exp = exp.Subtract(1);
                ++decimalPrec;
            }
            EInteger adjExpUpperBound = exp.Add(decimalPrec).Subtract(1);
            EInteger adjExpLowerBound = exp;

            // DebugUtility.Log("exp=" + adjExpLowerBound + "~" + (adjExpUpperBound));
            if (adjExpUpperBound.CompareTo(-326) < 0)
            {
                return(EFloat.SignalUnderflow(ctx, negative, zeroMantissa));
            }
            else if (adjExpLowerBound.CompareTo(309) > 0)
            {
                return(EFloat.SignalOverflow(ctx, negative, zeroMantissa));
            }
            if (zeroMantissa)
            {
                EFloat ef = EFloat.Create(
                    EInteger.Zero,
                    exp);
                if (negative)
                {
                    ef = ef.Negate();
                }
                return(ef.RoundToPrecision(ctx));
            }
            else if (decimalDigitStart != decimalDigitEnd)
            {
                if (digitEnd - digitStart == 1 && chars[digitStart] == '0')
                {
                    mant = EInteger.FromSubstring(
                        chars,
                        decimalDigitStart,
                        decimalDigitEnd);
                }
                else
                {
                    char[] ctmpstr = Extras.CharsConcat(
                        chars,
                        digitStart,
                        digitEnd - digitStart,
                        chars,
                        decimalDigitStart,
                        decimalDigitEnd - decimalDigitStart);
                    mant = EInteger.FromString(ctmpstr);
                }
            }
            else
            {
                mant = EInteger.FromSubstring(chars, digitStart, digitEnd);
            }
            if (nonzeroBeyondMax)
            {
                mant = mant.Multiply(10).Add(1);
            }
            if (negative)
            {
                mant = mant.Negate();
            }
            return(EDecimal.Create(mant, exp).ToEFloat(ctx));
        }
Example #29
0
    public EInteger[] FindCachedPowerOrSmaller(EInteger bi) {
      EInteger[] ret = null;
      EInteger minValue = null;
      if (bi.CanFitInInt32()) {
        return this.FindCachedPowerIntOrSmaller(bi.ToInt32Checked());
      }
      lock (this.outputs) {
        for (var i = 0; i < this.size; ++i) {
          if (this.inputs[i].CompareTo(bi) <= 0 && (minValue == null ||
          this.inputs[i].CompareTo(minValue) >= 0)) {
 // DebugUtility.Log("Have cached power (" + inputs[i] + "," + bi + ") ");
            ret = new EInteger[2];
            ret[0] = this.inputs[i];
            ret[1] = this.outputs[i];
            minValue = this.inputs[i];
          }
        }
      }
      return ret;
    }
Example #30
0
        private T RoundBeforeOp(T val, EContext ctx)
        {
            if (ctx == null || !ctx.HasMaxPrecision)
            {
                return(val);
            }
            int thisFlags = this.GetHelper().GetFlags(val);

            if ((thisFlags & BigNumberFlags.FlagSpecial) != 0)
            {
                return(val);
            }
            FastInteger fastPrecision = FastInteger.FromBig(ctx.Precision);
            EInteger    mant          = this.GetHelper().GetMantissa(val).Abs();
            FastInteger digits        =
                this.GetHelper().CreateShiftAccumulator(mant).GetDigitLength();
            EContext ctx2 = ctx.WithBlankFlags().WithTraps(0);

            if (digits.CompareTo(fastPrecision) <= 0)
            {
                // 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)
                return(val);
            }
            val = this.wrapper.RoundToPrecision(val, ctx2);
            // the only time rounding can signal an invalid
            // operation is if an operand is signaling NaN, but
            // this was already checked beforehand
      #if DEBUG
            if ((ctx2.Flags & EContext.FlagInvalid) != 0)
            {
                throw new
                      ArgumentException("doesn't satisfy (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.FlagSubnormal) != 0)
            {
                // Console.WriteLine("Subnormal input: " + val);
            }
            if ((ctx2.Flags & EContext.FlagUnderflow) != 0)
            {
                // Console.WriteLine("Underflow");
            }
            if ((ctx2.Flags & EContext.FlagOverflow) != 0)
            {
                bool neg = (thisFlags & BigNumberFlags.FlagNegative) != 0;
                ctx.Flags |= EContext.FlagLostDigits;
                return(this.SignalOverflow2(ctx, neg));
            }
            return(val);
        }
Example #31
0
 public EInteger GetCachedPower(EInteger bi) {
   if (bi.CanFitInInt32()) {
     return this.GetCachedPowerInt(bi.ToInt32Checked());
   }
   lock (this.outputs) {
     for (var i = 0; i < this.size; ++i) {
       if (bi.Equals(this.inputs[i])) {
         if (i != 0) {
           EInteger tmp;
           // Move to head of cache if it isn't already
           tmp = this.inputs[i]; this.inputs[i] = this.inputs[0];
           this.inputs[0] = tmp;
           int tmpi = this.inputsInts[i]; this.inputsInts[i] =
           this.inputsInts[0]; this.inputsInts[0] = tmpi;
           tmp = this.outputs[i]; this.outputs[i] = this.outputs[0];
           this.outputs[0] = tmp;
           // Move formerly newest to next newest
           if (i != 1) {
             tmp = this.inputs[i]; this.inputs[i] = this.inputs[1];
             this.inputs[1] = tmp;
             tmpi = this.inputsInts[i]; this.inputsInts[i] =
             this.inputsInts[1]; this.inputsInts[1] = tmpi;
             tmp = this.outputs[i]; this.outputs[i] = this.outputs[1];
             this.outputs[1] = tmp;
           }
         }
         return this.outputs[0];
       }
     }
   }
   return null;
 }
Example #32
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 |= BigNumberFlags.UnderflowFlags;
                    }
                }
            }
            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().CreateShiftAccumulator(mant).GetDigitLength();
                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.AsEInteger(),
                        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.AsEInteger(),
                    thisFlags);
            }
            return(thisValue);
        }
Example #33
0
 internal static EInteger FindPowerOfFiveFromBig(EInteger diff) {
   int sign = diff.Sign;
   if (sign < 0) {
     return EInteger.Zero;
   }
   if (sign == 0) {
     return EInteger.One;
   }
   FastInteger intcurexp = FastInteger.FromBig(diff);
   if (intcurexp.CompareToInt(54) <= 0) {
     return FindPowerOfFive(intcurexp.AsInt32());
   }
   EInteger mantissa = EInteger.One;
   EInteger bigpow;
   EInteger origdiff = diff;
   bigpow = ValuePowerOfFiveCache.GetCachedPower(origdiff);
   if (bigpow != null) {
     return bigpow;
   }
   EInteger[] otherPower =
   ValuePowerOfFiveCache.FindCachedPowerOrSmaller(origdiff);
   if (otherPower != null) {
     intcurexp.SubtractBig(otherPower[0]);
     bigpow = otherPower[1];
     mantissa = bigpow;
   } else {
     bigpow = EInteger.Zero;
   }
   while (intcurexp.Sign > 0) {
     if (intcurexp.CompareToInt(27) <= 0) {
       bigpow = FindPowerOfFive(intcurexp.AsInt32());
       mantissa *= (EInteger)bigpow;
       break;
     }
     if (intcurexp.CompareToInt(9999999) <= 0) {
       bigpow = FindPowerOfFive(1).Pow(intcurexp.AsInt32());
       mantissa *= (EInteger)bigpow;
       break;
     }
     if (bigpow.IsZero) {
       bigpow = FindPowerOfFive(1).Pow(9999999);
     }
     mantissa *= bigpow;
     intcurexp.AddInt(-9999999);
   }
   ValuePowerOfFiveCache.AddPower(origdiff, mantissa);
   return mantissa;
 }
Example #34
0
   /// <include file='../../docs.xml'
   /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.Xor(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/>
   public static EInteger Xor(EInteger a, EInteger b) {
     if (a == null) {
       throw new ArgumentNullException("a");
     }
     if (b == null) {
       throw new ArgumentNullException("b");
     }
     if (a == b) {
       return EInteger.Zero;
     }
     if (a.wordCount == 0) {
       return b;
     }
     if (b.wordCount == 0) {
       return a;
     }
     var valueXaNegative = false; int valueXaWordCount = 0;
     var valueXaReg = new short[a.wordCount];
     Array.Copy(a.words, valueXaReg, valueXaReg.Length);
     var valueXbNegative = false;
     var valueXbReg = new short[b.wordCount];
     Array.Copy(b.words, valueXbReg, valueXbReg.Length);
     valueXaNegative = a.negative;
     valueXaWordCount = a.wordCount;
     valueXbNegative = b.negative;
     valueXaReg = CleanGrow(
 valueXaReg,
 Math.Max(valueXaReg.Length, valueXbReg.Length));
     valueXbReg = CleanGrow(
 valueXbReg,
 Math.Max(valueXaReg.Length, valueXbReg.Length));
     if (valueXaNegative) {
       TwosComplement(valueXaReg, 0, (int)valueXaReg.Length);
     }
     if (valueXbNegative) {
       TwosComplement(valueXbReg, 0, (int)valueXbReg.Length);
     }
     valueXaNegative ^= valueXbNegative;
     XorWords(valueXaReg, valueXaReg, valueXbReg, (int)valueXaReg.Length);
     if (valueXaNegative) {
       TwosComplement(valueXaReg, 0, (int)valueXaReg.Length);
     }
     valueXaWordCount = CountWords(valueXaReg);
     return (valueXaWordCount == 0) ? EInteger.Zero : (new
       EInteger(valueXaWordCount, valueXaReg, valueXaNegative));
   }
Example #35
0
    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;
    }
Example #36
0
   /// <include file='../../docs.xml'
   /// path='docs/doc[@name="M:PeterO.Numbers.EInteger.ModPow(PeterO.Numbers.EInteger,PeterO.Numbers.EInteger,PeterO.Numbers.EInteger)"]/*'/>
   public static EInteger ModPow(
 EInteger bigintValue,
 EInteger pow,
 EInteger mod) {
     if (bigintValue == null) {
       throw new ArgumentNullException("bigintValue");
     }
     return bigintValue.ModPow(pow, mod);
   }
Example #37
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Numbers.EContext.ExponentWithinRange(PeterO.Numbers.EInteger)"]/*'/>
 public bool ExponentWithinRange(EInteger exponent) {
   if (exponent == null) {
     throw new ArgumentNullException("exponent");
   }
   if (!this.HasExponentRange) {
     return true;
   }
   if (this.bigintPrecision.IsZero) {
     // Only check EMax, since with an unlimited
     // precision, any exponent less than EMin will exceed EMin if
     // the mantissa is the right size
     return exponent.CompareTo(this.EMax) <= 0;
   } else {
     EInteger bigint = exponent;
     if (this.adjustExponent) {
       bigint += (EInteger)this.bigintPrecision;
       bigint -= EInteger.One;
     }
     return (bigint.CompareTo(this.EMin) >= 0) &&
       (exponent.CompareTo(this.EMax) <= 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;
    }
  }
Example #39
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Numbers.EContext.WithBigPrecision(PeterO.Numbers.EInteger)"]/*'/>
 public EContext WithBigPrecision(EInteger bigintPrecision) {
   if (bigintPrecision == null) {
     throw new ArgumentNullException("bigintPrecision");
   }
   if (bigintPrecision.Sign < 0) {
     throw new ArgumentException("bigintPrecision's sign (" +
       bigintPrecision.Sign + ") is less than 0");
   }
   EContext pc = this.Copy();
   pc.bigintPrecision = bigintPrecision;
   return pc;
 }
 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;
 }
Example #41
0
   private static EInteger FuzzInteger(
 EInteger ei,
 int fuzzes,
 RandomGenerator r) {
     byte[] bytes = ei.ToBytes(true);
     int bits = ei.GetUnsignedBitLength();
     for (var i = 0; i < fuzzes; ++i) {
       int bit = r.UniformInt(bits);
       bytes[bit / 8] ^= (byte)(1 << (bit & 0x07));
     }
     return EInteger.FromBytes(bytes, true);
   }
    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 #43
0
 private static void TestGcdPair(
   EInteger biga,
   EInteger bigb,
   EInteger biggcd) {
   EInteger ba = biga.Gcd(bigb);
   EInteger bb = bigb.Gcd(biga);
   Assert.AreEqual(ba, biggcd);
   Assert.AreEqual(bb, biggcd);
 }
 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);
 }
Example #45
0
 public static void AssertAdd(EInteger bi, EInteger bi2, string s) {
   EIntegerTest.AssertBigIntegersEqual(s, bi + (EInteger)bi2);
   EIntegerTest.AssertBigIntegersEqual(s, bi2 + (EInteger)bi);
   EInteger negbi = EInteger.Zero - (EInteger)bi;
   EInteger negbi2 = EInteger.Zero - (EInteger)bi2;
   EIntegerTest.AssertBigIntegersEqual(s, bi - (EInteger)negbi2);
   EIntegerTest.AssertBigIntegersEqual(s, bi2 - (EInteger)negbi);
 }
Example #46
0
 internal static int[] GetLastWords(EInteger bigint, int numWords32Bit)
 {
     return
         (MutableNumber.FromEInteger(bigint).GetLastWordsInternal(numWords32Bit));
 }