private static int CompareBaseBits(int bitsPerDigit, long n) { //middle digit <= n * (base - 1) ^ 2 + [2^(128 - bitsPerDigit)] <= P - 1 ulong[] value = new ulong[1]; ulong[] square = new ulong[value.Length * 2]; ulong[] multiplier = new ulong[square.Length]; ulong[] result = new ulong[square.Length * 2]; ulong[] adder = new ulong[result.Length]; value[0] = (1UL << bitsPerDigit) - 1; multiplier[0] = (ulong)n; AsmX64Operations.Square(value, square, value.Length); AsmX64Operations.Multiply(square, multiplier, result, square.Length); if (128 - bitsPerDigit < 64) { adder[0] = 1UL << (128 - bitsPerDigit); } else { adder[1] = 1UL << (64 - bitsPerDigit); } AsmX64Operations.Add(result, adder, result, 0, result.Length); if (result[2] > 0 || result[3] > 0 || (result[0] >= FourierPoint.PrimeModulo.Low && result[1] == ulong.MaxValue)) { return(1); } if (result[0] == FourierPoint.PrimeModulo.Low - 1 && result[1] == ulong.MaxValue) { return(0); } return(-1); }
public static IntegerNumber operator +(IntegerNumber number1, IntegerNumber number2) { if (number1.IsNegative != number2.IsNegative) { return(number2.IsZero ? number1 : number1 - (-number2)); } IntegerNumber source1 = number1.ExtendTo(number2.Digits); IntegerNumber source2 = number2.ExtendTo(number1.Digits); ulong[] result = new ulong[source1.Digits]; byte carry = AsmX64Operations.Add(source1.bits, source2.bits, result, 0, result.Length); if (carry != (byte)(result[result.Length - 1] >> 63)) { Array.Resize(ref result, result.Length + 1); result[result.Length - 1] = carry == 0 ? 0UL : ulong.MaxValue; } return(new IntegerNumber(result, false)); }