public void BasicAdditionMultiplicationTest() { var value = new Natural(ulong.MaxValue); Assert.AreEqual(value + value, value * 2); Assert.AreEqual(value + value + value, value * 3); }
public Integer(long value) { this.sign = value < 0 ? (sbyte)(-1) : (sbyte)1; if (value == Int64.MinValue) this.magnitude = new Natural((ulong)Int64.MaxValue) + 1; else this.magnitude = new Natural((ulong)Math.Abs(value)); }
public Natural Factorial() { var result = new Natural(1); for (Natural i = new Natural(1); i <= this; i++) { result = result * i; } return result; }
public static void Divide(Natural a, Natural b, out Natural quotient, out Natural remainder) { // Taken from http://en.wikipedia.org/wiki/Division_algorithm#Integer_division_.28unsigned.29_with_remainder if (b == 0) throw new DivideByZeroException(); remainder = 0; List<bool> q = new List<bool>(); foreach (var bit in a.WalkBits()) { remainder *= 2; if (bit) remainder += 1; if (remainder >= b) { remainder = (remainder - b).Magnitude; q.Add(true); } else q.Add(false); } List<uint> uints = new List<uint>(); uint current = 0; uint currentMask = 0x1; while (q.Count > 0) { if (currentMask == 0) { uints.Add(current); currentMask = 0x1; current = 0; } if (q[q.Count - 1]) current |= currentMask; q.RemoveAt(q.Count - 1); currentMask = currentMask << 1; } uints.Add(current); if (uints.Count == 0) quotient = 0; else { var tail = uints[0]; uints.RemoveAt(0); uints.Reverse(); while (uints.Count > 0 && uints[0] == 0) uints.RemoveAt(0); quotient = new Natural(tail, uints.ToArray()); } }
public static Natural operator *(Natural a, Natural b) { if (a.head.Length < b.head.Length) return b * a; List<Natural> partialProducts = new List<Natural>(b.head.Length + 1); partialProducts.Add(a * b.tail); for (var i = 0; i < b.head.Length; i++) { var product = a * b.head[i]; var newHead = new uint[product.head.Length + i + 1]; product.head.CopyTo(newHead, 0); newHead[product.head.Length] = product.tail; product = new Natural(0, newHead); partialProducts.Add(product); } return partialProducts.Aggregate((u, v) => u + v); }
public void BasicComparisonTest() { var value = GetRandomUlong(); var v1 = new Natural(value); var v2 = v1 * GetRandomUlong(); Assert.IsTrue(v2 > v1); Assert.IsFalse(v1 > v2); Assert.IsTrue(v1 < v2); Assert.IsFalse(v2 < v1); Assert.IsTrue(v2 >= v2); Assert.IsTrue(v2 >= v1); Assert.IsFalse(v1 >= v2); Assert.IsTrue(v1 <= v1); Assert.IsTrue(v1 <= v2); Assert.IsFalse(v2 <= v1); }
public void BasicEquality() { var value = GetRandomUlong(); var v1 = new Natural(value); var v2 = new Natural(value); Assert.IsTrue(v1.Equals(v2)); Assert.IsTrue(v2.Equals(v1)); Assert.IsTrue(v1 == v2); Assert.IsTrue(v1 == value); Assert.IsTrue(v2 == value); }
public void CastUlongToUintOverflow() { var value = UInt64.MaxValue; var bignum = new Natural(value); Assert.AreEqual(value, (ulong)bignum); var uintValue = (uint)bignum; // Should overflow }
public Integer(int value) { this.sign = value < 0 ? (sbyte)(-1) : (sbyte)1; this.magnitude = new Natural((ulong)Math.Abs((long)value)); }
public Integer(sbyte sign, Natural magnitude) { this.sign = sign; this.magnitude = magnitude; }
static bool CompareEqualLengthHeads(Natural a, Natural b, Func<uint, uint, bool> op) { for (var i = 0; i < a.head.Length; i++) { if (a.head[i] == b.head[i]) continue; return op(a.head[i], b.head[i]); } return op(a.tail, b.tail); }
public static bool Equals(Natural a, Natural b) { if (a.tail != b.tail) return false; if (a.head.Length != b.head.Length) return false; for (int i = 0; i < a.head.Length; i++) { if (a.head[i] != b.head[i]) return false; } return true; }