public static void Multiply(out Int128 c, ref Int128 a, ref Int128 b) { if (a.IsNegative) { UInt128 aneg; UInt128.Negate(out aneg, ref a.v); if (b.IsNegative) { UInt128 bneg; UInt128.Negate(out bneg, ref b.v); UInt128.Multiply(out c.v, ref aneg, ref bneg); } else { UInt128.Multiply(out c.v, ref aneg, ref b.v); UInt128.Negate(ref c.v); } } else { if (b.IsNegative) { UInt128 bneg; UInt128.Negate(out bneg, ref b.v); UInt128.Multiply(out c.v, ref a.v, ref bneg); UInt128.Negate(ref c.v); } else { UInt128.Multiply(out c.v, ref a.v, ref b.v); } } Debug.Assert((BigInteger)c == (BigInteger)a * (BigInteger)b); }
public static void Divide(out Int128 c, ref Int128 a, int b) { if (a.IsNegative) { UInt128 aneg; UInt128.Negate(out aneg, ref a.v); if (b < 0) { UInt128.Multiply(out c.v, ref aneg, (uint)(-b)); } else { UInt128.Multiply(out c.v, ref aneg, (uint)b); UInt128.Negate(ref c.v); } } else { if (b < 0) { UInt128.Multiply(out c.v, ref a.v, (uint)(-b)); UInt128.Negate(ref c.v); } else { UInt128.Multiply(out c.v, ref a.v, (uint)b); } } Debug.Assert((BigInteger)c == (BigInteger)a / (BigInteger)b); }
public void Multiply0ShouldReturn0() { Assert.AreEqual(UInt128.Zero, UInt128.Multiply(0, 0)); Assert.AreEqual(UInt128.Zero, UInt128.Multiply(0, 1)); Assert.AreEqual(UInt128.Zero, UInt128.Multiply(1, 0)); Assert.AreEqual(UInt128.Zero, UInt128.Multiply(0, ulong.MaxValue)); }
public static void Multiply(out Int128 c, ref Int128 a, long b) { if (a.IsNegative) { UInt128 aneg; UInt128.Negate(out aneg, ref a.v); if (b < 0) { UInt128.Multiply(out c.v, ref aneg, (ulong)(-b)); } else { UInt128.Multiply(out c.v, ref aneg, (ulong)b); UInt128.Negate(ref c.v); } } else { if (b < 0) { UInt128.Multiply(out c.v, ref a.v, (ulong)(-b)); UInt128.Negate(ref c.v); } else { UInt128.Multiply(out c.v, ref a.v, (ulong)b); } } //Debug.Assert((BigInteger)c == (BigInteger)a * (BigInteger)b); }
public static ulong ModularProduct(ulong a, ulong b, ulong modulus) { UInt128 product; UInt128.Multiply(out product, a, b); var c = UInt128.Remainder(ref product, modulus); Debug.Assert((BigInteger)a * b % modulus == c); return(c); }
public static void Multiply(out Int128 c, ref Int128 a, ulong b) { if (a.IsNegative) { UInt128 aneg; UInt128.Negate(out aneg, ref a.v); UInt128.Multiply(out c.v, ref aneg, b); UInt128.Negate(ref c.v); } else UInt128.Multiply(out c.v, ref a.v, b); Debug.Assert((BigInteger)c == (BigInteger)a * (BigInteger)b); }
public static void SubtractProduct(ref Int128 a, ref UInt128 b, long c) { UInt128 d; if (c < 0) { UInt128.Multiply(out d, ref b, (ulong)(-c)); UInt128.Add(ref a.v, ref d); } else { UInt128.Multiply(out d, ref b, (ulong)c); UInt128.Subtract(ref a.v, ref d); } }
public static void AddProduct(ref Int128 a, ref UInt128 b, long c) { UInt128 product; if (c < 0) { UInt128.Multiply(out product, ref b, (ulong)(-c)); UInt128.Subtract(ref a.v, ref product); } else { UInt128.Multiply(out product, ref b, (ulong)c); UInt128.Add(ref a.v, ref product); } }
/// <summary>Compute the modulo (division remainder) of a number raised to the power /// of another number.</summary> /// <remarks>Overflow safe for all input values. </remarks> /// <param name="value">The number to raise to the exponent power.</param> /// <param name="exponent">The exponent to raise value by.</param> /// <param name="modulus">The number by which to divide value raised to the exponent power.</param> /// <returns>The remainder after dividing value raised to the exponent power.</returns> public static ulong ModPow(this ulong value, ulong exponent, ulong modulus) { if (modulus == 0) { return(0); } value %= modulus; if (value == 0) { return(0); } if (exponent < 3) { if (exponent == 0) { return(1); } if (exponent == 1) { return(value); } if (exponent == 2) { var sqr = UInt128.Square(value); return((modulus == (uint)modulus) ? sqr.Mod((uint)modulus) : sqr.Mod(modulus)); } } if (modulus == (uint)modulus) { return(ModPow(value, exponent, (uint)modulus)); } ulong result = 1; if ((exponent & 1) == 1) { result = value; } while ((exponent /= 2) != 0) { value = UInt128.Square(value).Mod(modulus); if ((exponent & 1) != 0) { result = UInt128.Multiply(result, value).Mod(modulus); } } return(result); }
public static T InvokeImpl(T arg1, T arg2) { if (null != default(T)) { if (typeof(Int32) == typeof(T)) { return((T)(object)checked ((Int32)(object)arg1 * (Int32)(object)arg2)); } else if (typeof(Int64) == typeof(T)) { return((T)(object)checked ((Int64)(object)arg1 * (Int64)(object)arg2)); } else if (typeof(UInt32) == typeof(T)) { return((T)(object)checked ((UInt32)(object)arg1 * (UInt32)(object)arg2)); } else if (typeof(UInt64) == typeof(T)) { return((T)(object)checked ((UInt64)(object)arg1 * (UInt64)(object)arg2)); } else if (typeof(Int16) == typeof(T)) { return((T)(object)checked ((Int16) unchecked ((int)(Int16)(object)arg1 * (int)(Int16)(object)arg2))); } else if (typeof(UInt16) == typeof(T)) { return((T)(object)checked ((UInt16) unchecked ((uint)(UInt16)(object)arg1 * (uint)(UInt16)(object)arg2))); } else if (typeof(Byte) == typeof(T)) { return((T)(object)checked ((Byte) unchecked ((uint)(Byte)(object)arg1 * (uint)(Byte)(object)arg2))); } else if (typeof(SByte) == typeof(T)) { return((T)(object)checked ((SByte) unchecked ((int)(SByte)(object)arg1 * (int)(SByte)(object)arg2))); } else if (typeof(Int128) == typeof(T)) { return((T)(object)(Int128.Multiply((Int128)(object)arg1, (Int128)(object)arg2))); } else if (typeof(UInt128) == typeof(T)) { return((T)(object)(UInt128.Multiply((UInt128)(object)arg1, (UInt128)(object)arg2))); } } return(InvokeImpl1(arg1, arg2)); }
/// <summary>Compute the modulo (division remainder) of a number multiplied by another number.</summary> /// <remarks>Overflow safe for all input values. </remarks> /// <param name="value1">The number to be multiplied by value2.</param> /// <param name="value2">The number to be multiplied by value1.</param> /// <param name="modulus">The number by which to divide value raised to the exponent power.</param> /// <returns>The remainder after dividing the product of multiplying value1 and value2.</returns> public static ulong MulMod(this ulong value1, ulong value2, ulong modulus) { return(UInt128.Multiply(value1, value2) % modulus); }
public static UInt128 Multiply(this UInt128 value, decimal d) { return(value.Multiply(Fraction.Get(d))); }
public static UInt128 Divide(this UInt128 value, decimal d) { return(value.Multiply(1m / d)); }
public void SquareShouldEqualMultiplySame() { Assert.AreEqual(UInt128.Square(ulong.MaxValue), UInt128.Multiply(ulong.MaxValue, ulong.MaxValue)); Assert.AreEqual(UInt128.Square(ulong.MaxValue / 3), UInt128.Multiply(ulong.MaxValue / 3, ulong.MaxValue / 3)); }
public void MultiplyMax() { Assert.AreEqual(new UInt128(ulong.MaxValue << 1, 1), UInt128.Multiply(ulong.MaxValue, ulong.MaxValue)); }
public void Multiply1ShouldReturnOther() { Assert.AreEqual(UInt128.One, UInt128.Multiply(1, 1)); Assert.AreEqual(new UInt128(0, ulong.MaxValue), UInt128.Multiply(1, ulong.MaxValue)); Assert.AreEqual(new UInt128(0, ulong.MaxValue), UInt128.Multiply(ulong.MaxValue, 1)); }