public void ShiftRight(FastInteger fastint) { if (fastint.Sign <= 0) { return; } if (fastint.CanFitInInt32()) { this.ShiftRightInt(fastint.ToInt32()); } else { EInteger bi = fastint.ToEInteger(); while (bi.Sign > 0) { var count = 1000000; if (bi.CompareTo((EInteger)1000000) < 0) { count = (int)bi; } this.ShiftRightInt(count); bi -= (EInteger)count; if (this.isSmall ? this.shiftedSmall == 0 : this.shiftedBigInt.IsZero) { break; } } } }
public static FastIntegerFixed FromFastInteger(FastInteger fi) { if (fi.CanFitInInt32()) { return(FromInt32(fi.ToInt32())); } else { return(FastIntegerFixed.FromBig(fi.ToEInteger())); } }
public void ShiftToDigits( FastInteger bits, FastInteger preShift, bool truncate) { if (bits.Sign < 0) { throw new ArgumentException("bits's sign(" + bits.Sign + ") is less than 0"); } if (preShift != null && preShift.Sign > 0) { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" + // (//kbl) + " [" + this.shiftedBigInt + "]"); if (this.knownBitLength.CompareTo(bits) <= 0) { // Known digit length is already small enough // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(preShift); VerifyKnownLength(); return; } else { FastInteger bitDiff = this.knownBitLength.Copy() .Subtract(bits); // DebugUtility.Log("bitDiff=" + bitDiff); int cmp = bitDiff.CompareTo(preShift); if (cmp <= 0) { // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(preShift); VerifyKnownLength(); return; } else { // NOTE: For BitShiftAccumulator, truncating and shifting // are the same, unlike in DigitShiftAccumulator this.ShiftRight(bitDiff); VerifyKnownLength(); return; } } } if (bits.CanFitInInt32()) { this.ShiftToDigitsInt(bits.ToInt32()); VerifyKnownLength(); } else { this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); EInteger bigintDiff = this.knownBitLength.ToEInteger(); EInteger bitsBig = bits.ToEInteger(); bigintDiff -= (EInteger)bitsBig; if (bigintDiff.Sign > 0) { // current length is greater than the // desired bit length this.ShiftRight(FastInteger.FromBig(bigintDiff)); } VerifyKnownLength(); } }
private void ShiftBigToBits(int bits) { // Shifts a number until it reaches the given number of bits, // gathering information on whether the last bit discarded is set and // whether the discarded bits to the right of that bit are set. Assumes // that the big integer being shifted is positive. if (this.knownBitLength != null) { if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } } this.knownBitLength = this.knownBitLength ?? this.CalcKnownBitLength(); if (this.knownBitLength.CompareToInt(bits) <= 0) { return; } // Shift by the difference in bit length if (this.knownBitLength.CompareToInt(bits) > 0) { var bs = 0; if (this.knownBitLength.CanFitInInt32()) { bs = this.knownBitLength.ToInt32(); bs -= bits; } else { FastInteger bitShift = this.knownBitLength.Copy().SubtractInt(bits); if (!bitShift.CanFitInInt32()) { this.ShiftRight(bitShift); return; } bs = bitShift.ToInt32(); } this.knownBitLength.SetInt(bits); this.discardedBitCount.AddInt(bs); if (bs == 1) { bool odd = !this.shiftedBigInt.IsEven; this.shiftedBigInt >>= 1; this.bitsAfterLeftmost |= this.bitLeftmost; this.bitLeftmost = odd ? 1 : 0; } else { this.bitsAfterLeftmost |= this.bitLeftmost; long lowestSet = this.shiftedBigInt.GetLowBitAsInt64(); if (lowestSet == Int64.MaxValue) { EInteger lowestSetBit = this.shiftedBigInt.GetLowBitAsEInteger(); if (lowestSetBit.CompareTo(bs - 1) < 0) { // One of the discarded bits after // the last one is set this.bitsAfterLeftmost |= 1; this.bitLeftmost = this.shiftedBigInt.GetSignedBit(bs - 1) ? 1 : 0; } else if (lowestSetBit.CompareTo(bs - 1) > 0) { // Means all discarded bits are zero this.bitLeftmost = 0; } else { // Only the last discarded bit is set this.bitLeftmost = 1; } } else { if (lowestSet < bs - 1) { // One of the discarded bits after // the last one is set this.bitsAfterLeftmost |= 1; this.bitLeftmost = this.shiftedBigInt.GetSignedBit(bs - 1) ? 1 : 0; } else if (lowestSet > bs - 1) { // Means all discarded bits are zero this.bitLeftmost = 0; } else { // Only the last discarded bit is set this.bitLeftmost = 1; } } this.shiftedBigInt >>= bs; } if (bits < SmallBitLength) { // Shifting to small number of bits, // convert to small integer this.isSmall = true; this.shiftedSmall = (int)this.shiftedBigInt; } this.bitsAfterLeftmost = (this.bitsAfterLeftmost != 0) ? 1 : 0; } }
/// <summary> </summary> /// <param name='bits'>A FastInteger object.</param> /// <returns></returns> public void ShiftToDigits(FastInteger bits) { if(bits.Sign<0) throw new ArgumentException("bits is negative"); if(bits.CanFitInInt32()){ ShiftToDigitsInt(bits.AsInt32()); } else { knownBitLength=CalcKnownBitLength(); BigInteger bigintDiff=knownBitLength.AsBigInteger(); BigInteger bitsBig=bits.AsBigInteger(); bigintDiff-=(BigInteger)bitsBig; if(bigintDiff.Sign>0){ // current length is greater than the // desired bit length ShiftRight(FastInteger.FromBig(bigintDiff)); } } }
/// <summary> </summary> /// <param name='fastint'>A FastInteger object.</param> /// <returns></returns> public void ShiftRight(FastInteger fastint) { if (fastint.Sign <= 0) return; if (fastint.CanFitInInt32()) { ShiftRightInt(fastint.AsInt32()); } else { BigInteger bi = fastint.AsBigInteger(); while (bi.Sign > 0) { int count = 1000000; if (bi.CompareTo((BigInteger)1000000) < 0) { count = (int)bi; } ShiftRightInt(count); bi -= (BigInteger)count; if(isSmall ? shiftedSmall==0 : shiftedBigInt.IsZero){ break; } } } }
public void TruncateRight(FastInteger fastint) { if (fastint == null) { throw new ArgumentNullException("fastint"); } if (fastint.CanFitInInt32()) { int fi = fastint.AsInt32(); if (fi < 0) { return; } if (!this.isSmall) { if (this.shiftedBigInt.CanFitInInt64()) { this.TruncateRightLong(this.shiftedBigInt.ToInt64Checked(), fi); } else { this.ShiftRightBig(fi, true); } } else { this.TruncateRightSmall(fi); } } else { this.ShiftRight(fastint); } }
public void ShiftToDigits( FastInteger bits, FastInteger preShift, bool truncate) { #if DEBUG if (bits.Sign < 0) { throw new ArgumentException("bits's sign (" + bits.Sign + ") is less than 0"); } #endif if (preShift != null && preShift.Sign > 0) { FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength(); this.knownDigitLength = kdl; // DebugUtility.Log("bits=" + bits + " pre=" + preShift + " known=" + // (//kdl) + " [" + this.shiftedBigInt + "]"); if (kdl.CompareTo(bits) <= 0) { // Known digit length is already small enough if (truncate) { this.TruncateRight(preShift); } else { this.ShiftRight(preShift); } this.VerifyKnownLength(); return; } else { FastInteger bitDiff = kdl.Copy().Subtract(bits); // DebugUtility.Log("bitDiff=" + bitDiff); int cmp = bitDiff.CompareTo(preShift); if (cmp <= 0) { // Difference between desired digit length and current // length is smaller than the shift, make it the shift if (truncate) { this.TruncateRight(preShift); } else { this.ShiftRight(preShift); } this.VerifyKnownLength(); return; } else { if (truncate) { this.TruncateRight(bitDiff); } else { this.ShiftRight(bitDiff); } this.VerifyKnownLength(); return; } } } if (bits.CanFitInInt32()) { int intval = bits.AsInt32(); if (intval < 0) { throw new ArgumentException("intval (" + intval + ") is less than " + "0"); } if (this.isSmall) { this.ShiftToDigitsSmall(intval); } else { this.ShiftToDigitsBig(intval, truncate); } this.VerifyKnownLength(); } else { FastInteger kdl = this.knownDigitLength ?? this.CalcKnownDigitLength(); this.knownDigitLength = kdl; this.VerifyKnownLength(); EInteger bigintDiff = kdl.AsEInteger(); EInteger bitsBig = bits.AsEInteger(); bigintDiff -= (EInteger)bitsBig; if (bigintDiff.Sign > 0) { // current length is greater than the // desired bit length this.ShiftRight(FastInteger.FromBig(bigintDiff)); } this.VerifyKnownLength(); } }
public void ShiftRight(FastInteger fastint) { if (fastint == null) { throw new ArgumentNullException("fastint"); } if (fastint.CanFitInInt32()) { int fi = fastint.AsInt32(); if (fi < 0) { return; } this.ShiftRightInt(fi); } else { if (fastint.Sign <= 0) { return; } EInteger bi = fastint.AsEInteger(); while (bi.Sign > 0) { var count = 1000000; if (bi.CompareTo((EInteger)1000000) < 0) { count = (int)bi; } this.ShiftRightInt(count); bi -= (EInteger)count; if (this.isSmall ? this.shiftedSmall == 0 : this.shiftedBigInt.IsZero) { break; } } } }
/// <summary> Parses a number whose format follows the JSON specification /// (RFC 4627). Roughly speaking, a valid number consists of an optional /// minus sign, one or more digits (starting with 1 to 9 unless the only /// digit is 0), an optional decimal point with one or more digits, and /// an optional letter E or e with one or more digits (the exponent). </summary> /// <param name='str'>A string to parse.</param> /// <param name='integersOnly'>If true, no decimal points or exponents /// are allowed in the string.</param> /// <param name='positiveOnly'>If true, only positive numbers are /// allowed (the leading minus is disallowed).</param> /// <param name='failOnExponentOverflow'>If true, this function /// will return null if the exponent is less than -(2^64) or greater than /// 2^64-1 (unless the value is 0). If false, this function will return /// a CBOR object representing positive or negative infinity if the exponent /// is greater than 2^64-1 (unless the value is 0), and will return zero /// if the exponent is less than -(2^64).</param> /// <returns>A CBOR object that represents the parsed number.</returns> public static CBORObject ParseJSONNumber(string str, bool integersOnly, bool positiveOnly, bool failOnExponentOverflow ) { if (String.IsNullOrEmpty(str)) return null; char c = str[0]; bool negative = false; int index = 0; if (index >= str.Length) return null; c = str[index]; if (c == '-' && !positiveOnly) { negative = true; index++; } if (index >= str.Length) return null; c = str[index]; index++; bool negExp = false; FastInteger fastNumber = new FastInteger(0); FastInteger exponentAdjust = new FastInteger(0); FastInteger fastExponent = new FastInteger(0); if (c >= '1' && c <= '9') { fastNumber.AddInt((int)(c - '0')); while (index < str.Length) { c = str[index]; if (c >= '0' && c <= '9') { index++; fastNumber.Multiply(10); fastNumber.AddInt((int)(c - '0')); } else { break; } } } else if (c != '0') { return null; } if (!integersOnly) { if (index < str.Length && str[index] == '.') { // Fraction index++; if (index >= str.Length) return null; c = str[index]; index++; if (c >= '0' && c <= '9') { // Adjust the exponent for this // fractional digit exponentAdjust.AddInt(-1); fastNumber.Multiply(10); fastNumber.AddInt((int)(c - '0')); while (index < str.Length) { c = str[index]; if (c >= '0' && c <= '9') { index++; // Adjust the exponent for this // fractional digit exponentAdjust.AddInt(-1); fastNumber.Multiply(10); fastNumber.AddInt((int)(c - '0')); } else { break; } } } else { // Not a fraction return null; } } if (index < str.Length && (str[index] == 'e' || str[index] == 'E')) { // Exponent index++; if (index >= str.Length) return null; c = str[index]; if (c == '-') { negExp = true; index++; } if (c == '+') index++; if (index >= str.Length) return null; c = str[index]; index++; if (c >= '0' && c <= '9') { fastExponent.AddInt((int)(c - '0')); while (index < str.Length) { c = str[index]; if (c >= '0' && c <= '9') { index++; fastExponent.Multiply(10); fastExponent.AddInt((int)(c - '0')); } else { break; } } } else { // Not an exponent return null; } } } if (negExp) fastExponent.Negate(); if (negative) fastNumber.Negate(); fastExponent.Add(exponentAdjust); if (index != str.Length) { // End of the string wasn't reached, so isn't a number return null; } // No fractional part if(fastExponent.Sign==0){ if(fastNumber.CanFitInInt32()) return CBORObject.FromObject(fastNumber.AsInt32()); else return CBORObject.FromObject(fastNumber.AsBigInteger()); } else { if(fastNumber.Sign==0){ return CBORObject.FromObject(0); } if(fastNumber.CanFitInInt32() && fastExponent.CanFitInInt32()){ return CBORObject.FromObject(new ExtendedDecimal( fastNumber.AsBigInteger(),fastExponent.AsBigInteger())); } else { BigInteger bigintExponent=fastExponent.AsBigInteger(); if(!fastExponent.CanFitInInt32()){ if (bigintExponent.CompareTo(UInt64MaxValue) > 0) { // Exponent is higher than the highest representable // integer of major type 0 if (failOnExponentOverflow) return null; else return (fastExponent.Sign < 0) ? CBORObject.FromObject(Double.NegativeInfinity) : CBORObject.FromObject(Double.PositiveInfinity); } if (bigintExponent.CompareTo(LowestMajorType1) < 0) { // Exponent is lower than the lowest representable // integer of major type 1 if (failOnExponentOverflow) return null; else return CBORObject.FromObject(0); } } return CBORObject.FromObject(new ExtendedDecimal( fastNumber.AsBigInteger(),bigintExponent)); } } }