// вычитание public static LongNumber Subtract(LongNumber first, LongNumber second) { var sum = new LongNumber(first._discharges); var isCarry = false; for (int i = 0; i < second._discharges.Count; i++) { var isCarryNext = sum._discharges[i] < second._discharges[i]; sum._discharges[i] -= ( byte )(second._discharges[i] + (isCarry ? 1 : 0)); isCarry = isCarryNext; } var carryIndex = second._discharges.Count; while (isCarry) { if (sum._discharges[carryIndex] != 0) { isCarry = false; } sum._discharges[carryIndex] -= 1; carryIndex++; } var lastIndex = sum._discharges.Count; while (lastIndex != 0 && sum._discharges[--lastIndex] == 0) { ; } sum._discharges.RemoveRange(lastIndex + 1, sum._discharges.Count - lastIndex - 1); return(sum); }
// широкую на широкую! умножаем public static LongNumber operator *(LongNumber first, LongNumber second) { var output = new LongNumber(); if (AbsCompare(first, second) == -1) { var temp = second; second = first; first = temp; } for (int i = 0; i < second._discharges.Count; i++) { multuADD(output, first * second._discharges[i], i); } var lastIndex = output._discharges.Count; while (lastIndex != 0 && output._discharges[--lastIndex] == 0) { ; } output._discharges.RemoveRange(lastIndex + 1, output._discharges.Count - lastIndex - 1); output._isNegative = first._isNegative != second._isNegative; return(output); }
// сранение 1 - первое больше, -1 первое меньше, 0 - равны public static int AbsCompare(LongNumber first, LongNumber second) { if (first._isNegative && !second._isNegative) { return(-1); } if (!first._isNegative && second._isNegative) { return(1); } if (first._discharges.Count < second._discharges.Count) { return(-1); } if (first._discharges.Count > second._discharges.Count) { return(1); } for (int i = first._discharges.Count - 1; i >= 0; i--) { if (first._discharges[i] < second._discharges[i]) { return(-1); } if (first._discharges[i] > second._discharges[i]) { return(1); } } return(0); }
// подбор очередного байта частного методом дихотомии. (гуглить "окулов длинная арифметика") private static Cont <Byte, LongNumber> getDivider(LongNumber residue, LongNumber second) { var down = 0; var up = 256; while (down + 1 < up) { var newValue = second * ( byte )((down + up) / 2); if (AbsCompare(residue, newValue) == -1) { up = (down + up) / 2; } else { down = (down + up) / 2; } } var residueOut = Subtract(residue, second * ( byte )down); residueOut._isNegative = residue._isNegative; return(new Cont <Byte, LongNumber>(( byte )down, residueOut)); }
public static bool MuTuallySimple(LongNumber number1, LongNumber number2) { if (number1 == new LongNumber(0) || number2 == new LongNumber(0)) { return(false); } return(LeastCommonDivisor(number1, number2) == new LongNumber(1)); }
public static LongNumber GetCopy(LongNumber MyList1) { LongNumber temp = new LongNumber(); for (int i = 0; i < MyList1.Length; i++) { temp.Push(MyList1[i]); } return(temp); }
// сложение public static LongNumber Add(LongNumber first, LongNumber second) { var sum = new LongNumber(first._discharges); var isCarry = false; for (int i = 0; i < second._discharges.Count; i++) { var add = sum._discharges[i] + second._discharges[i] + (isCarry ? 1 : 0); isCarry = (add >> 8) > 0; sum._discharges[i] = ( byte )add; } var carryIndex = second._discharges.Count; return(sum); }
// деление (частное, остаток) public static Cont <LongNumber, LongNumber> operator /(LongNumber first, LongNumber second) { var output = new LongNumber(); var residue = new LongNumber(first._discharges, first._isNegative); if (AbsCompare(first, second) == -1) { output._discharges.Add(0); return(new Cont <LongNumber, LongNumber>(output, residue)); } var discharge = residue._discharges.Count - second._discharges.Count; for (int i = 0; i < discharge; i++) { second._discharges.Insert(0, 0); } for (int i = 0; i < discharge; i++) { if (AbsCompare(residue, second) == -1) { output._discharges.Insert(0, 0); } else { var cont = getDivider(residue, second); output._discharges.Insert(0, cont.First); residue = cont.Second; } second._discharges.RemoveAt(0); } { var cont = getDivider(residue, second); output._discharges.Insert(0, cont.First); residue = cont.Second; } var lastIndex = output._discharges.Count; while (output._discharges[--lastIndex] == 0) { ; } output._discharges.RemoveRange(lastIndex + 1, output._discharges.Count - lastIndex - 1); output._isNegative = first._isNegative != second._isNegative; return(new Cont <LongNumber, LongNumber>(output, residue)); }
// специальное сложение для умножения. чтоб быстрее private static void multuADD(LongNumber output, LongNumber longNumber, int index) { var isCarry = false; for (int i = 0; i < longNumber._discharges.Count; i++) { if (output._discharges.Count == i + index) { output._discharges.Add(0); } var add = output._discharges[i + index] + longNumber._discharges[i] + (isCarry ? 1 : 0); isCarry = (add >> 8) > 0; output._discharges[i + index] = ( byte )add; } var carryIndex = longNumber._discharges.Count + index; }
// перевод в обычную строку(поразрядно) public override string ToString() { var sb = new StringBuilder(); sb.Append(Sign()); var forOut = new LongNumber(_discharges); var ten = new LongNumber(new byte[] { 10 }); while (forOut._discharges.Count > 1 || forOut._discharges[0] > 9) { var div = forOut / ten; forOut = div.First; sb.Insert(1, ( char )('0' + div.Second._discharges[0])); } sb.Insert(1, ( char )('0' + forOut._discharges[0])); return(sb.ToString()); }
// перегруз оператора. учтено, что иногда сложение - это вычитание (например -5+3 - это 3 - 5) public static LongNumber operator -(LongNumber first, LongNumber second) { if (first == second) { second = new LongNumber(second._discharges) { _isNegative = !first._isNegative } } ; else { second._isNegative = !second._isNegative; } var output = first + second; second._isNegative = !second._isNegative; return(output); }
// умножение длинного на байт public static LongNumber operator *(LongNumber ln, byte b) { var output = new LongNumber(ln._discharges); byte carry = 0; for (int i = 0; i < output._discharges.Count; i++) { int intermediate = output._discharges[i] * b; var addCarry = ((intermediate & 255) + carry) >> 8; output._discharges[i] = ( byte )((intermediate & 255) + carry); carry = ( byte )((intermediate >> 8) + addCarry); } if (carry > 0) { output._discharges.Add(carry); } return(output); }
public static LongNumber FromString(string s) { if (s.Length != 0 && s[0] != '-' && s[0] != '+') { s = '+' + s; } var output = new LongNumber(new List <byte> { 0 }); for (int i = 1; i < s.Length; i++) { output *= 10; output += new LongNumber(new List <byte> { ( byte )(s[i] - '0') }); } output._isNegative = s[0] == '-'; return(output); }
public static LongNumber operator %(LongNumber number1, LongNumber number2) { if (number1 == number2) { return(new LongNumber(0)); } if (number1 < number2) { return(GetCopy(number1)); } int i = number1.Length - 1; LongNumber temp = new LongNumber(); while (i >= 0) { temp.InsertToStart(number1[i]); i--; if (temp[temp.Length - 1] == 0 && temp.Length > 1) { temp.Pop(); } while (temp < number2 && i >= 0) { temp.InsertToStart(number1[i]); i--; } while (temp >= number2) { temp = temp - number2; } } return(temp); }
public static LongNumber LeastCommonDivisor(LongNumber number1, LongNumber number2) { if (number1 >= number2) { LongNumber temp = number1 % number2; if (temp == new LongNumber(0)) { return(GetCopy(number2)); } return(LeastCommonDivisor(number2, temp)); } else { LongNumber temp = number2 % number1; if (temp == new LongNumber(0)) { return(GetCopy(number1)); } return(LeastCommonDivisor(number1, temp)); } }
static void Main(string[] args) { Console.WriteLine("Enter the first number\n"); string string_number1 = Console.ReadLine(); Console.WriteLine("Enter the second number\n"); string string_number2 = Console.ReadLine(); LongNumber number1 = new LongNumber(string_number1); LongNumber number2 = new LongNumber(string_number2); if (LongNumber.MuTuallySimple(number1, number2)) { Console.WriteLine("\nMutually simple\n"); } else { Console.WriteLine("\nNot mutually simple\n"); } Console.ReadKey(); }
public static LongNumber operator -(LongNumber number1, LongNumber number2) { /* * * for(int i=1;i<number1_0+1;i++) * { * * if(i<number1_0) //если не первый разряд * { * result[i+1]--; //занимаем единицу у более старшего разряда большого числа * result[i]+=10+big[i]; * } * else * result[i]+=big[i]; * * result[i]-=small[i]; * if(result[i]/10>0) * { * result[i+1]++; * result[i]%=10; * } * }*/ if (number1 < number2) { return(null); } if (number1 == number2) { return(new LongNumber(0)); } LongNumber result = new LongNumber(0); for (int i = 0; i < number1.Length; i++) { if (i < number1.Length - 1) { result.Push(0); (result)[i + 1] = (result)[i + 1] - 1; (result)[i] = (result)[i] + 10 + number1[i]; } else { result[i] = result[i] + number1[i]; } if (i < number2.Length) { result[i] = result[i] - number2[i]; } if (result[i] / 10 > 0 && i < number1.Length - 1) { ((MyList)result)[i + 1] = ((MyList)result)[i + 1] + 1; result[i] = result[i] % 10; } } int j = result.Length - 1; while (result[j] <= 0 && j > 0) { result.Pop(); j--; } return(result); }
public LongNumber(LongNumber ln) { _isNegative = ln._isNegative; _discharges = ln._discharges; }