/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Negate"]/*'/> internal FastInteger Negate() { this.CheckFrozen(); switch (this.integerMode) { case 0: if (this.smallValue == Int32.MinValue) { // would overflow, convert to large this.integerMode = 1; this.mnum = MutableNumber.FromEInteger(ValueNegativeInt32MinValue); } else { smallValue = -smallValue; } break; case 1: this.integerMode = 2; this.largeValue = this.mnum.ToEInteger(); this.largeValue = -(EInteger)this.largeValue; break; case 2: this.largeValue = -(EInteger)this.largeValue; break; default: throw new InvalidOperationException(); } return(this); }
public int CompareTo(MutableNumber other) { if (this.wordCount != other.wordCount) { return((this.wordCount < other.wordCount) ? -1 : 1); } int valueN = this.wordCount; while (unchecked (valueN--) != 0) { int an = this.data[valueN]; int bn = other.data[valueN]; // Unsigned less-than check if (((an >> 31) == (bn >> 31)) ? ((an & Int32.MaxValue) < (bn & Int32.MaxValue)) : ((an >> 31) == 0)) { return(-1); } if (an != bn) { return(1); } } return(0); }
internal FastInteger AddInt(int val) { this.CheckFrozen(); EInteger valValue; switch (this.integerMode) { case 0: if ((this.smallValue < 0 && (int)val < Int32.MinValue - this.smallValue) || (this.smallValue > 0 && (int)val > Int32.MaxValue - this.smallValue)) { // would overflow if (val >= 0) { this.integerMode = 1; this.mnum = new MutableNumber(this.smallValue); this.mnum.Add(val); } else { this.integerMode = 2; this.largeValue = (EInteger)this.smallValue; this.largeValue += (EInteger)val; } } else { smallValue += val; } break; case 1: if (val >= 0) { this.mnum.Add(val); } else { integerMode = 2; largeValue = mnum.ToEInteger(); valValue = (EInteger)val; largeValue += (EInteger)valValue; } break; case 2: valValue = (EInteger)val; this.largeValue += (EInteger)valValue; break; default: throw new InvalidOperationException(); } return(this); }
internal MutableNumber Copy() { var mbi = new MutableNumber(0); if (this.wordCount > mbi.data.Length) { mbi.data = new int[this.wordCount]; } Array.Copy(this.data, mbi.data, this.wordCount); mbi.wordCount = this.wordCount; return(mbi); }
internal FastInteger Divide(int divisor) { this.CheckFrozen(); if (divisor != 0) { switch (this.integerMode) { case 0: if (divisor == -1 && this.smallValue == Int32.MinValue) { // would overflow, convert to large this.integerMode = 1; this.mnum = MutableNumber.FromEInteger(ValueNegativeInt32MinValue); } else { smallValue /= divisor; } break; case 1: this.integerMode = 2; this.largeValue = this.mnum.ToEInteger(); this.largeValue /= (EInteger)divisor; if (this.largeValue.IsZero) { this.integerMode = 0; this.smallValue = 0; } break; case 2: this.largeValue /= (EInteger)divisor; if (this.largeValue.IsZero) { this.integerMode = 0; this.smallValue = 0; } break; default: throw new InvalidOperationException(); } } else { throw new DivideByZeroException(); } return(this); }
internal MutableNumber Subtract(MutableNumber other) { unchecked { { // Console.WriteLine("" + this.data.Length + " " + // (other.data.Length)); int neededSize = (this.wordCount > other.wordCount) ? this.wordCount : other.wordCount; if (this.data.Length < neededSize) { var newdata = new int[neededSize + 20]; Array.Copy(this.data, 0, newdata, 0, this.data.Length); this.data = newdata; } neededSize = (this.wordCount < other.wordCount) ? this.wordCount : other.wordCount; var u = 0; var borrow = 0; for (var i = 0; i < neededSize; ++i) { int a = this.data[i]; u = (a - other.data[i]) - borrow; borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) < (u & Int32.MaxValue)) : ((a >> 31) == 0)) || (a == u && other.data[i] != 0)) ? 1 : 0; this.data[i] = (int)u; } if (borrow != 0) { for (int i = neededSize; i < this.wordCount; ++i) { int a = this.data[i]; u = (a - other.data[i]) - borrow; borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) < (u & Int32.MaxValue)) : ((a >> 31) == 0)) || (a == u && other.data[i] != 0)) ? 1 : 0; this.data[i] = (int)u; } } // Calculate the correct data length while (this.wordCount != 0 && this.data[this.wordCount - 1] == 0) { --this.wordCount; } return(this); } } }
internal FastInteger Increment() { this.CheckFrozen(); if (this.integerMode == 0) { if (this.smallValue != Int32.MaxValue) { ++this.smallValue; } else { this.integerMode = 1; this.mnum = MutableNumber.FromEInteger(ValueNegativeInt32MinValue); } return(this); } return(this.AddInt(1)); }
internal static MutableNumber FromEInteger(EInteger bigintVal) { var mnum = new MutableNumber(0); if (bigintVal.Sign < 0) { throw new ArgumentException("bigintVal's sign (" + bigintVal.Sign + ") is less than " + "0 "); } byte[] bytes = bigintVal.ToBytes(true); int len = bytes.Length; int newWordCount = Math.Max(4, (len / 4) + 1); if (newWordCount > mnum.data.Length) { mnum.data = new int[newWordCount]; } mnum.wordCount = newWordCount; unchecked { for (var i = 0; i < len; i += 4) { int x = ((int)bytes[i]) & 0xff; if (i + 1 < len) { x |= (((int)bytes[i + 1]) & 0xff) << 8; } if (i + 2 < len) { x |= (((int)bytes[i + 2]) & 0xff) << 16; } if (i + 3 < len) { x |= (((int)bytes[i + 3]) & 0xff) << 24; } mnum.data[i >> 2] = x; } } // Calculate the correct data length while (mnum.wordCount != 0 && mnum.data[mnum.wordCount - 1] == 0) { --mnum.wordCount; } return(mnum); }
public static MutableNumber FromLong(long longVal) { if (longVal < 0) { throw new ArgumentException(); } if (longVal == 0) { return(new MutableNumber(0)); } var mbi = new MutableNumber(0); mbi.data[0] = unchecked ((int)longVal); int mbd = unchecked ((int)(longVal >> 32)); mbi.data[1] = mbd; mbi.wordCount = (mbd == 0) ? 1 : 2; return(mbi); }
internal FastInteger Decrement() { this.CheckFrozen(); if (this.integerMode == 0) { if (this.smallValue != Int32.MinValue) { --this.smallValue; } else { this.integerMode = 1; this.mnum = MutableNumber.FromEInteger(ValueInt32MinValue); this.mnum.SubtractInt(1); } return(this); } return(this.SubtractInt(1)); }
internal static FastInteger FromBig(EInteger bigintVal) { if (bigintVal.CanFitInInt32()) { return(new FastInteger(bigintVal.ToInt32Unchecked())); } if (bigintVal.Sign > 0) { var fi = new FastInteger(0); fi.integerMode = 1; fi.mnum = MutableNumber.FromEInteger(bigintVal); return(fi); } else { var fi = new FastInteger(0); fi.integerMode = 2; fi.largeValue = bigintVal; return(fi); } }
internal FastInteger2 Add(FastInteger2 val) { 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.AsBigInteger(); 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.AsBigInteger(); largeValue += (EInteger)valValue; } break; case 2: valValue = val.AsBigInteger(); this.largeValue += (EInteger)valValue; break; default: throw new InvalidOperationException(); } return this; }
internal MutableNumber Subtract(MutableNumber other) { unchecked { { // Console.WriteLine("" + this.data.Length + " " + // (other.data.Length)); int neededSize = (this.wordCount > other.wordCount) ? this.wordCount : other.wordCount; if (this.data.Length < neededSize) { var newdata = new int[neededSize + 20]; Array.Copy(this.data, 0, newdata, 0, this.data.Length); this.data = newdata; } neededSize = (this.wordCount < other.wordCount) ? this.wordCount : other.wordCount; var u = 0; var borrow = 0; for (var i = 0; i < neededSize; ++i) { int a = this.data[i]; u = (a - other.data[i]) - borrow; borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) < (u & Int32.MaxValue)) : ((a >> 31) == 0)) || (a == u && other.data[i] != 0)) ? 1 : 0; this.data[i] = (int)u; } if (borrow != 0) { for (int i = neededSize; i < this.wordCount; ++i) { int a = this.data[i]; u = (a - other.data[i]) - borrow; borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) < (u & Int32.MaxValue)) : ((a >> 31) == 0)) || (a == u && other.data[i] != 0)) ? 1 : 0; this.data[i] = (int)u; } } // Calculate the correct data length while (this.wordCount != 0 && this.data[this.wordCount - 1] == 0) { --this.wordCount; } return this; } } }
/// <include file='../../docs.xml' /// path='docs/doc[@name="M:PeterO.Cbor.FastInteger2.Multiply(System.Int32)"]/*'/> internal FastInteger2 Multiply(int val) { if (val == 0) { this.smallValue = 0; this.integerMode = 0; } else { switch (this.integerMode) { case 0: bool apos = this.smallValue > 0L; bool bpos = val > 0L; if ( (apos && ((!bpos && (Int32.MinValue / this.smallValue) > val) || (bpos && this.smallValue > (Int32.MaxValue / val)))) || (!apos && ((!bpos && this.smallValue != 0L && (Int32.MaxValue / this.smallValue) > val) || (bpos && this.smallValue < (Int32.MinValue / val))))) { // would overflow, convert to large if (apos && bpos) { // if both operands are nonnegative // convert to mutable big integer this.integerMode = 1; this.mnum = new MutableNumber(this.smallValue); this.mnum.Multiply(val); } else { // if either operand is negative // convert to big integer this.integerMode = 2; this.largeValue = (EInteger)this.smallValue; this.largeValue *= (EInteger)val; } } else { smallValue *= val; } 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; }
/// <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); }
internal static int[] GetLastWords(EInteger bigint, int numWords32Bit) { return (MutableNumber.FromEInteger(bigint).GetLastWordsInternal(numWords32Bit)); }