/// <summary> /// Multiplies two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> /// <exception cref="ArgumentNullException"><paramref name="int1" /> or <paramref name="int2" /> is a null reference.</exception> /// <exception cref="ArgumentException"><paramref name="int1" /> or <paramref name="int2" /> is too big for multiply operation.</exception> public virtual IntX Multiply(IntX int1, IntX int2) { // Exceptions if (ReferenceEquals(int1, null)) { throw new ArgumentNullException("int1", Strings.CantBeNull); } else if (ReferenceEquals(int2, null)) { throw new ArgumentNullException("int2", Strings.CantBeNull); } // Special behavior for zero cases if (int1._length == 0 || int2._length == 0) return new IntX(); // Get new big integer length and check it ulong newLength = (ulong)int1._length + int2._length; if (newLength >> 32 != 0) { throw new ArgumentException(Strings.IntegerTooBig); } // Create resulting big int IntX newInt = new IntX((uint)newLength, int1._negative ^ int2._negative); // Perform actual digits multiplication newInt._length = Multiply(int1._digits, int1._length, int2._digits, int2._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return newInt; }
/// <summary> /// Performs bitwise NOT for big integer. /// </summary> /// <param name="value">Big integer.</param> /// <returns>Resulting big integer.</returns> static public IntX OnesComplement(IntX value) { // Exceptions if (ReferenceEquals(value, null)) { throw new ArgumentNullException("value", Strings.CantBeNull); } // Process zero values in special way if (value._length == 0) { return(new IntX()); } // Create new big int object of needed length IntX newInt = new IntX(value._length, !value._negative); // Do actual operation newInt._length = DigitOpHelper.OnesComplement( value._digits, value._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return(newInt); }
/// <summary> /// Subtracts two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> static public IntX Sub(IntX int1, IntX int2) { // Process zero values in special way if (int1._length == 0) { return(new IntX(int2._digits, true)); } if (int2._length == 0) { return(new IntX(int1)); } // Determine lower big int (without sign) IntX smallerInt; IntX biggerInt; int compareResult = DigitOpHelper.Cmp(int1._digits, int1._length, int2._digits, int2._length); if (compareResult == 0) { return(new IntX()); // integers are equal } if (compareResult < 0) { smallerInt = int1; biggerInt = int2; } else { smallerInt = int2; biggerInt = int1; } // Create new big int object IntX newInt = new IntX(biggerInt._length, ReferenceEquals(int1, smallerInt) ^ int1._negative); // Do actual subtraction newInt._length = DigitOpHelper.Sub( biggerInt._digits, biggerInt._length, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return(newInt); }
/// <summary> /// Performs bitwise XOR for two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> static public IntX ExclusiveOr(IntX int1, IntX int2) { // Exceptions if (ReferenceEquals(int1, null)) { throw new ArgumentNullException("int1", Strings.CantBeNull); } if (ReferenceEquals(int2, null)) { throw new ArgumentNullException("int2", Strings.CantBeNull); } // Process zero values in special way if (int1._length == 0) { return(new IntX(int2)); } if (int2._length == 0) { return(new IntX(int1)); } // Determine big int with lower length IntX smallerInt; IntX biggerInt; DigitHelper.GetMinMaxLengthObjects(int1, int2, out smallerInt, out biggerInt); // Create new big int object of needed length IntX newInt = new IntX(biggerInt._length, int1._negative ^ int2._negative); // Do actual operation newInt._length = DigitOpHelper.ExclusiveOr( biggerInt._digits, biggerInt._length, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return(newInt); }
/// <summary> /// Adds two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> /// <exception cref="ArgumentException"><paramref name="int1" /> or <paramref name="int2" /> is too big for add operation.</exception> static public IntX Add(IntX int1, IntX int2) { // Process zero values in special way if (int2._length == 0) { return(new IntX(int1)); } if (int1._length == 0) { IntX x = new IntX(int2); x._negative = int1._negative; // always get sign of the first big integer return(x); } // Determine big int with lower length IntX smallerInt; IntX biggerInt; DigitHelper.GetMinMaxLengthObjects(int1, int2, out smallerInt, out biggerInt); // Check for add operation possibility if (biggerInt._length == uint.MaxValue) { throw new ArgumentException(Strings.IntegerTooBig); } // Create new big int object of needed length IntX newInt = new IntX(biggerInt._length + 1, int1._negative); // Do actual addition newInt._length = DigitOpHelper.Add( biggerInt._digits, biggerInt._length, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return(newInt); }
/// <summary> /// Adds two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> /// <exception cref="ArgumentException"><paramref name="int1" /> or <paramref name="int2" /> is too big for add operation.</exception> static public IntX Add(IntX int1, IntX int2) { // Process zero values in special way if (int2._length == 0) return new IntX(int1); if (int1._length == 0) { IntX x = new IntX(int2); x._negative = int1._negative; // always get sign of the first big integer return x; } // Determine big int with lower length IntX smallerInt; IntX biggerInt; DigitHelper.GetMinMaxLengthObjects(int1, int2, out smallerInt, out biggerInt); // Check for add operation possibility if (biggerInt._length == uint.MaxValue) { throw new ArgumentException(Strings.IntegerTooBig); } // Create new big int object of needed length IntX newInt = new IntX(biggerInt._length + 1, int1._negative); // Do actual addition newInt._length = DigitOpHelper.Add( biggerInt._digits, biggerInt._length, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return newInt; }
/// <summary> /// Multiplies two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> /// <exception cref="ArgumentNullException"><paramref name="int1" /> or <paramref name="int2" /> is a null reference.</exception> /// <exception cref="ArgumentException"><paramref name="int1" /> or <paramref name="int2" /> is too big for multiply operation.</exception> virtual public IntX Multiply(IntX int1, IntX int2) { // Exceptions if (ReferenceEquals(int1, null)) { throw new ArgumentNullException("int1", Strings.CantBeNull); } else if (ReferenceEquals(int2, null)) { throw new ArgumentNullException("int2", Strings.CantBeNull); } // Special behavior for zero cases if (int1._length == 0 || int2._length == 0) { return(new IntX()); } // Get new big integer length and check it ulong newLength = (ulong)int1._length + int2._length; if (newLength >> 32 != 0) { throw new ArgumentException(Strings.IntegerTooBig); } // Create resulting big int IntX newInt = new IntX((uint)newLength, int1._negative ^ int2._negative); // Perform actual digits multiplication newInt._length = Multiply(int1._digits, int1._length, int2._digits, int2._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return(newInt); }
/// <summary> /// Subtracts two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> static public IntX Sub(IntX int1, IntX int2) { // Process zero values in special way if (int1._length == 0) return new IntX(int2._digits, true); if (int2._length == 0) return new IntX(int1); // Determine lower big int (without sign) IntX smallerInt; IntX biggerInt; int compareResult = DigitOpHelper.Cmp(int1._digits, int1._length, int2._digits, int2._length); if (compareResult == 0) return new IntX(); // integers are equal if (compareResult < 0) { smallerInt = int1; biggerInt = int2; } else { smallerInt = int2; biggerInt = int1; } // Create new big int object IntX newInt = new IntX(biggerInt._length, ReferenceEquals(int1, smallerInt) ^ int1._negative); // Do actual subtraction newInt._length = DigitOpHelper.Sub( biggerInt._digits, biggerInt._length, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return newInt; }
/// <summary> /// Performs bitwise AND for two big integers. /// </summary> /// <param name="int1">First big integer.</param> /// <param name="int2">Second big integer.</param> /// <returns>Resulting big integer.</returns> public static IntX BitwiseAnd(IntX int1, IntX int2) { // Exceptions if (ReferenceEquals(int1, null)) { throw new ArgumentNullException("int1", Strings.CantBeNull); } if (ReferenceEquals(int2, null)) { throw new ArgumentNullException("int2", Strings.CantBeNull); } // Process zero values in special way if (int1._length == 0 || int2._length == 0) { return new IntX(); } // Determine big int with lower length IntX smallerInt; IntX biggerInt; DigitHelper.GetMinMaxLengthObjects(int1, int2, out smallerInt, out biggerInt); // Create new big int object of needed length IntX newInt = new IntX(smallerInt._length, int1._negative & int2._negative); // Do actual operation newInt._length = DigitOpHelper.BitwiseAnd( biggerInt._digits, smallerInt._digits, smallerInt._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return newInt; }
/// <summary> /// Performs bitwise NOT for big integer. /// </summary> /// <param name="value">Big integer.</param> /// <returns>Resulting big integer.</returns> public static IntX OnesComplement(IntX value) { // Exceptions if (ReferenceEquals(value, null)) { throw new ArgumentNullException("value", Strings.CantBeNull); } // Process zero values in special way if (value._length == 0) { return new IntX(); } // Create new big int object of needed length IntX newInt = new IntX(value._length, !value._negative); // Do actual operation newInt._length = DigitOpHelper.OnesComplement( value._digits, value._length, newInt._digits); // Normalization may be needed newInt.TryNormalize(); return newInt; }