// вычитание
        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;
 }