Beispiel #1
0
        public static LongNumber operator *(LongNumber x, int y)  // Перегрузка умножения длинного и обычного числа.
        {
            // Запоминаем длину числа.
            int xn = x.num.Count;
            // Переменная для ответа.
            LongNumber a = new LongNumber();

            // В ответе есть ячейка с нулём, удаляем её, чтобы можно было работать только с методом Add.
            a.num.RemoveAt(0);
            // Запоминаем знак короткого числа и меняем это число, если оно меньше нуля, для удобства.
            int sign;

            if (y >= 0)
            {
                sign = 1;
            }
            else
            {
                sign = -1;
                y   *= -1;
            }
            // Переменные для текущего результата и переноса.
            int b = 0;
            int p = 0;

            // Если входное число меньше 10.
            if (y / 10 == 0)
            {
                // Умножаем его на длинное.
                for (int i = 0; i < xn; i++)
                {
                    b = x.num[i] * y + p;
                    p = b / 10;
                    a.num.Add(b % 10);
                }
                // Если после умножения остался перенос, записываем его в новую ячейку.
                if (p > 0)
                {
                    a.num.Add(p);
                }
                // Записываем знак.
                a.sign = x.sign * sign;
            }
            // Если входное число из нескольких цифр.
            else
            {
                // Превращаем его в длинное и считаем произведение длинных.
                string     s  = Convert.ToString(y);
                LongNumber y0 = new LongNumber(s);
                a.EqualTo(x * y0);
            }
            a.exp = x.exp;
            // Удаляем нули и возвращаем.
            a.RemoveZeros();
            return(a);
        }
Beispiel #2
0
        public LongNumber Abs(LongNumber x) // Метод, возвращающий модуль числа.
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber();

            // Присваиваем, чтобы не менять исходную переменную.
            a.EqualTo(x);
            // Возвращаем модуль знака и возвращаем число.
            a.sign = Math.Abs(a.sign);
            return(a);
        }
Beispiel #3
0
        public static LongNumber operator +(LongNumber x, int y)  // Сложение длинного и обычного чисел.
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber();
            // Превращаем число в длинное.
            string     s  = Convert.ToString(y);
            LongNumber y1 = new LongNumber(s);

            // Считаем сумму длинных чисел.
            a.EqualTo(x + y1);
            return(a);
        }
Beispiel #4
0
 public static LongNumber Min(LongNumber x, LongNumber y) // Метод нахождения минимального.
 {
     // Если первое больше, возвращаем второе, инача - первое.
     if (x > y)
     {
         return(y);
     }
     else
     {
         return(x);
     }
 }
Beispiel #5
0
        public static LongNumber Task6(int k) // Задача номер СЕМЬ!
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber("2");
            // Переменная для текущего результата.
            LongNumber q = new LongNumber("1");
            // Переменная для проверки точности.
            LongNumber w = new LongNumber("1");
            // "Длинная" единица для удобства.
            LongNumber x = new LongNumber("1");
            // Итерационная переменная.
            int i = 2;
            // Пременная для знака.
            int p = -1;

            // Пока не дошли до указанной точности и не вышли за границы int32.
            while ((a.GetExp() <= k * 2) && (i < int.MaxValue))
            {
                // Считаем.
                q.SetMaxExp(k);
                q.EqualTo(x / i);
                q.EqualTo(q * p);
                a.EqualTo(a + q);
                // Проверяем точность.
                w.EqualTo(a - w);
                int j = a.num.Count;
                if (a.GetExp() > k)
                {
                    while (j >= k)
                    {
                        if (w.num[j - 1] != 0)
                        {
                            break;
                        }
                        j--;
                    }
                    if (j <= k)
                    {
                        break;
                    }
                }
                // Сохраняем текущий результат.
                w.EqualTo(a);
                // Двигаем итерацию.
                i += 2;
                // Меняем знак.
                p *= -1;
            }
            a.EqualTo(a * 2);
            return(a);
        }
Beispiel #6
0
        static void Main(string[] args)
        {
            LongNumber a = new LongNumber();

            Console.WriteLine("В этой программке работают 1, 4, 6, 7, 10, 13 и 16 задачи.");
            Console.WriteLine("Введите число К для первой задачи.");
            int k = Convert.ToInt32(Console.ReadLine());

            a.EqualTo(Task1(k));
            Console.WriteLine("Сиё есть 1 задача.");
            a.WriteOut();
            Console.WriteLine("Введите два длинных числа для 4 задачи.");
            string     s  = Console.ReadLine();
            string     s1 = Console.ReadLine();
            LongNumber x1 = new LongNumber(s);
            LongNumber y1 = new LongNumber(s1);

            a.EqualTo(x1 * y1);
            Console.WriteLine("Сиё есть умножение.");
            a.WriteOut();
            a.EqualTo(x1 / y1);
            Console.WriteLine("Сиё есть деление.");
            a.WriteOut();
            Console.WriteLine("Введите число знаков для шестой задачи.");
            k = Convert.ToInt32(Console.ReadLine());
            a.EqualTo(Task6(k));
            a.WriteOut();
            Console.WriteLine("Введите число знаков для седьмой задачи.");
            k = Convert.ToInt32(Console.ReadLine());
            a.EqualTo(Task7(k));
            a.WriteOut();
            Console.WriteLine("Введите основание и степень для 10 задачи.");
            s  = Console.ReadLine();
            s1 = Console.ReadLine();
            x1 = new LongNumber(s);
            y1 = new LongNumber(s1);
            a.EqualTo(Task10(x1, y1));
            Console.WriteLine("Сиё есть 10 задача.");
            a.WriteOut();
            Console.WriteLine("Введите число Х для тринадцатой задачи.");
            s  = Console.ReadLine();
            x1 = new LongNumber(s);
            a.EqualTo(Task13(x1));
            Console.WriteLine("Сиё есть 13 задача.");
            a.WriteOut();
            Console.WriteLine("Сиё есть 16 задача.");
            Task16();
        }
Beispiel #7
0
        public static LongNumber Task10(LongNumber k, LongNumber n)  // Задача номер ДЕСЯТЬ!
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber();
            // Длинная единица, для удобства.
            LongNumber b = new LongNumber("1");

            // Считаем сумму геометрической прогрессии.
            a.EqualTo(k);
            LongNumber.UpToPow(a, n);
            a.EqualTo(b - a);
            b.EqualTo(b - k);
            a.EqualTo(a / b);
            a.RemoveZeros();
            return(a);
        }
Beispiel #8
0
 public void EqualTo(LongNumber x) // Метод присваивания.
 {
     // Присваиваем экспоненту и знак.
     this.exp    = x.exp;
     this.sign   = x.sign;
     this.maxexp = x.maxexp;
     // Удаляем всё в исходном числе.
     this.num.RemoveRange(0, this.num.Count);
     // Записываем мантиссу входного числа в исходное.
     for (int i = 0; i < x.num.Count; i++)
     {
         this.num.Add(x.num[i]);
     }
     // Удаляем лишние нули.
     this.RemoveZeros();
 }
Beispiel #9
0
        public static void Task16() // Задача номер ШЕСТНАДЦАТЬ!
        {
            // Массив со степенями.
            int[]      p = new int[] { 2, 3, 5, 7, 13, 17, 19, 31, 61, 89 };
            LongNumber q = new LongNumber("2");
            LongNumber b = new LongNumber("1");
            // Переменная для ответа.
            LongNumber a = new LongNumber();

            // Идём по степеням в массиве и считаем числа Мерсенна.
            for (int i = 0; i < 10; i++)
            {
                a.EqualTo(q);
                a.EqualTo(LongNumber.UpToPow(a, p[i]));
                a.EqualTo(a - b);
                a.WriteOut();
            }
        }
Beispiel #10
0
        public static LongNumber Task1(int k)  // Задача номер ОДИН!
        {
            // Переменные для ответа.
            LongNumber a = new LongNumber("1");
            LongNumber x = new LongNumber("1");
            // Дополнительная переменная.
            int p;

            // Собственно, сам счёт.
            for (int i = 2; i <= k; i++)
            {
                p = i * i;
                x.EqualTo(a * p);
                a.EqualTo(a + x);
            }
            // Возвращаем.
            a.RemoveZeros();
            return(a);
        }
Beispiel #11
0
        public static LongNumber Task13(LongNumber x)  // Задача номер ТРИНАДЦАТЬ!
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber();
            // Длинная единица, для удобства.
            LongNumber b = new LongNumber("1");

            // Если модуль икса больше единицы.
            if (x.Abs(x) > b)
            {
                // Возвращаем ноль.
                return(a);
            }
            // Если всё нормально.
            else
            {
                // Считаем 100 шагов.
                int n = 100;
                // Переменная для текущего шага.
                // Считаем со 2 шага, поэтому изначально она равна первому шагу, то бишь иксу.
                LongNumber k = new LongNumber("1");
                k.EqualTo(x);
                // Переменная для знака.
                int        p = 1;
                LongNumber y = new LongNumber("1");
                // Считаем ряд со второго шага в цикле.
                for (int i = 2; i <= n; i += 2)
                {
                    k.EqualTo(k * x);
                    k.EqualTo(k * x);
                    k.EqualTo(k * p);
                    y.EqualTo(y * (i * (i - 1)));
                    k.EqualTo(k / y);
                    p *= -1;
                    a.EqualTo(a + k);
                }
                // Удаляем лишние нули и возвращаем.
                a.RemoveZeros();
                return(a);
            }
        }
Beispiel #12
0
        public static LongNumber UpToPow(LongNumber x1, LongNumber y1) // Бинарное возведение в степень.
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber("1");
            // "Длинная" единица, для удобства.
            LongNumber b = new LongNumber("1");
            // Сохраняем входные данные, т.к., возможно, будем их менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            a.EqualTo(x);
            // Если степень целая, считаем.
            if (y.exp == 0)
            {
                if ((y.num.Count == 1) && (y.num[0] == 0))
                {
                    return(b);
                }
                if (y.num[0] % 2 == 1)
                {
                    y.EqualTo(y - b);
                    y.EqualTo(UpToPow(x, y));
                    y.EqualTo(y * x);
                    return(y);
                }
                else
                {
                    y.EqualTo(y / 2);
                    a.EqualTo(UpToPow(x, y));
                    a.EqualTo(a * a);
                    return(a);
                }
            }
            // Удаляем лишние нули и возвращаем.
            a.RemoveZeros();
            return(a);
        }
Beispiel #13
0
        public static LongNumber operator *(LongNumber x1, LongNumber y1)  // Перегрузка умножения длинных чисел.
        {
            // Создаём переменную для ответа.
            LongNumber a = new LongNumber();
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            // Запоминаем длины чисел.
            int xn = x.num.Count, yn = y.num.Count;
            // Переменная для текущего результата.
            LongNumber n = new LongNumber();

            n.EqualTo(y * x.num[0]);
            a.EqualTo(a + n);
            // Перебираем цифры в первом числе.
            for (int i = 1; i < xn; i++)
            {
                // Умножаем цифру первого числа на второе.
                n.EqualTo(y * x.num[i]);
                // Сдвигаем текущий результат на позицию цифры.
                for (int j = 0; j < i; j++)
                {
                    n.num.Insert(0, 0);
                }
                // Складываем с ответом.
                a.EqualTo(a + n);
            }
            // Экпонента ответа - сумма экспонент.
            a.exp = x.exp + y.exp;
            // Удаляем лишние нули.
            a.RemoveZeros();
            // Перемножаем знаки и возвращаем.
            a.sign = x.sign * y.sign;
            return(a);
        }
Beispiel #14
0
        public static LongNumber operator -(LongNumber x1, LongNumber y1)  // Перегрузка оператора вычитанияы
        {
            // Создаём переменную для ответа.
            LongNumber a = new LongNumber();
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            // Запоминаем длины чисел.
            int xn = x.num.Count, yn = y.num.Count;

            // Если уменьшаемое короче, делаем так: x-y=-y+x=-(y-x).
            if (xn - x.exp < yn - y.exp)
            {
                x.sign *= -1;
                y.sign *= -1;
                a.EqualTo(y - x);
                a.RemoveZeros();
                return(a);
            }
            // Проверяем равенство знаков.
            if (x.sign == y.sign)
            {
                // Переменные для текущего результата и переноса.
                int b = 0;
                int p = 0;
                // Удаляем все ячейки в переменной ответа.
                a.num.RemoveAt(0);
                // Разница в длинах дробных частей.
                int c = Math.Abs(x.exp - y.exp);
                // Сравниваем длины дробных частей.
                if (x.exp >= y.exp)
                {
                    // Если первое не короче второго (дробная часть), перепысываем более длинную часть в ответ.
                    for (int i = 0; i < c; i++)
                    {
                        a.num.Add(x.num[i]);
                    }
                    // Считаем общую часть.
                    for (int i = c; i < Math.Min(xn, yn + c); i++)
                    {
                        b = x.num[i] - y.num[i - c] - p;
                        // Если текущий результат меньше нуля, добавляем к нему основание и занимаем единицу.
                        if (b < 0)
                        {
                            b += 10;
                            p  = 1;
                        }
                        else
                        {
                            p = 0;
                        }
                        a.num.Add(b);
                    }
                    // Уменьшаемое не короче вычитаемого, поэтому считаем более длинную часть, если она есть.
                    for (int i = yn + c; i < xn; i++)
                    {
                        b = x.num[i] - p;
                        if (b < 0)
                        {
                            b += 10;
                            p  = 1;
                        }
                        else
                        {
                            p = 0;
                        }
                        a.num.Add(b);
                    }
                    // Записываем в ответ экспоненту.
                    a.exp = x.exp;
                }
                else
                {
                    // Если у второго длинная часть больше, вычитаем более длинную часть из нулей.
                    for (int i = 0; i < c; i++)
                    {
                        b = 10 - p - y.num[i];
                        p = 1;
                        a.num.Add(b);
                    }
                    // Считаем общую часть.
                    for (int i = c; i < yn; i++)
                    {
                        b = x.num[i - c] - y.num[i] - p;
                        if (b < 0)
                        {
                            p  = 1;
                            b += 10;
                        }
                        else
                        {
                            p = 0;
                        }
                        a.num.Add(b);
                    }
                    // Уменьшаемое не короче вычитаемого, поэтому считаем более длинную часть, если она есть.
                    for (int i = yn - c; i < xn; i++)
                    {
                        b = x.num[i] - p;
                        if (b < 0)
                        {
                            p  = 1;
                            b += 10;
                        }
                        else
                        {
                            p = 0;
                        }
                        a.num.Add(b);
                    }
                    a.exp = y.exp;
                }
                // Записываем знак.
                a.sign = y.sign;
                // Проверяем, осталось ли что-то в переносе.
                if (p > 0)
                {
                    // Если осталось, вычитаем ответ из старшего разряда и меняем знак.
                    a.RemoveZeros();
                    p = 0;
                    for (int i = 0; i < a.num.Count; i++)
                    {
                        b        = 10 - a.num[i] - p;
                        p        = 1;
                        a.num[i] = b;
                    }
                    a.sign *= -1;
                }
            }
            else
            {
                // Если знаки не равны, меняем знак и считаем сумму.
                y.sign *= -1;
                a.EqualTo(x + y);
            }
            // Удаляем лишние нули и возвращаем.
            a.RemoveZeros();
            return(a);
        }
Beispiel #15
0
        public static LongNumber UpToPow(LongNumber x, int y)
        {
            LongNumber a = new LongNumber(Convert.ToString(y));

            return(UpToPow(x, a));
        }
Beispiel #16
0
        public static LongNumber operator /(LongNumber x1, LongNumber y1)
        {
            // Переменная для ответа.
            LongNumber a = new LongNumber();
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            // Запоминаем длины чисел.
            int xn = x.num.Count, yn = y.num.Count;
            // Переменная для переноса.
            int p = 0;

            // Если у второго числа есть дробная часть.
            if (y.exp > 0)
            {
                // Если у первого она не меньше, двигаем оба, пока второе не станет целым.
                if (x.exp >= y.exp)
                {
                    x.exp -= y.exp;
                    y.exp  = 0;
                }
                // Если у первого она меньше, добавляем нули и двигаем оба.
                else
                {
                    for (int i = 0; i < y.exp - x.exp; i++)
                    {
                        x.num.Insert(0, 0);
                        xn++;
                    }
                    y.exp = 0;
                    x.exp = 0;
                }
            }
            // Разность длин чисел.
            int c = xn - yn;

            // Двигаем левое число до конца правого, если оно короче, с запоминанием исходной позиции.
            for (int i = 0; i < c - 1; i++)
            {
                y.num.Insert(0, 0);
            }
            //
            p = x.num[xn - 1];
            // Переменная для сохранения предыдущего результата.
            LongNumber q = new LongNumber();
            // Переменная для проверки длины чисел.
            LongNumber w = new LongNumber();
            // Флаг для проверки.
            bool b = true;
            // Переменная для ранения текущей позиции запятой.
            int e = 0;
            // Переменная для сохранения точности.
            int e1 = x.maxexp;

            // Пока не дошли до удвоенной точности.
            while ((b) && (e <= x.maxexp * 2))
            {
                // Пока первое число не меньше второго, вычитаем из него второе.
                while (!(x < y))
                {
                    x.EqualTo(x - y);
                    a.PlusOne();
                }
                // Если первое число превратилось в ноль.
                if ((x.num.Count == 1) && (x.num[0] == 0))
                {
                    // Если второе число всё ещё сдвинуто, добавляем нужное число нулей и выходим из цикла.
                    if (y.num.Count > yn)
                    {
                        for (int j = 0; j < yn; j++)
                        {
                            a.num.Insert(0, 0);
                        }
                    }
                    break;
                }
                // Если первое не ноль и второе сдвинуто, двигаем второе на один разряд обратно.
                if (y.num.Count > yn)
                {
                    y.num.RemoveAt(0);
                }
                // Если первое не ноль и второе не сдвинуто.
                else
                {
                    // Увеличиваем позицию запятой в ответе.
                    e++;
                    // Если не дошли до указанной точности, добавляем ноль в первое число.
                    if (e <= e1)
                    {
                        x.num.Insert(0, 0);
                    }
                    // Если дошли.
                    else
                    {
                        // Сравниваем значения текущего и предыдущего шагов.
                        w.EqualTo(a - q);
                        // Идём с позиции запятой до указанной точности.
                        int j = x.num.Count;
                        while (j >= e1)
                        {
                            // Если есть не ноль в разности, выходим из цикла.
                            if (w.num[j - 1] != 0)
                            {
                                break;
                            }
                            j--;
                        }
                        // Если дошли до указанной точности,
                        // то бишь, в разности текущего и предыдущего все нули,
                        // то бишь, разряды текущего шага до указанной точности не изменились,
                        // выходим из цикла.
                        if (j <= e1)
                        {
                            break;
                        }
                    }
                }
                // Сохраняем значение текущего шага.
                q.EqualTo(a);
                // Добавляем разряд в ответ.
                a.num.Insert(0, 0);
            }
            // Записываем экспоненту в ответ.
            a.exp = e + x.exp;
            // Записываем знак в ответ и возвращаем.
            a.sign = x.sign * y.sign;
            return(a);
        }
Beispiel #17
0
        public static LongNumber operator /(LongNumber x1, int y)  // Перегрузка деления.
        {
            // Переменная ддля ответа.
            LongNumber a = new LongNumber();
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            // Интовое число не сохраняем, т.к. оно передаётся по значению и исходное меняться не будет.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            // Запоминаем длину.
            int xn = x.num.Count;
            // Переменные для текущего результата и переноса.
            int b = 0;
            int p = 0;

            // Если короткое число меньше нуля, меняем его знак. Знак ответа противоположен знаку первого числа.
            if (y < 0)
            {
                a.sign = x.sign * (-1);
                y     *= -1;
            }
            // Иначе знак ответа равен знаку первого числа.
            else
            {
                a.sign = x.sign;
            }
            // Если во втором числе одна цифра.
            if (y / 10 == 0)
            {
                // Делаем ответ полностью пустым, для удобства.
                a.num.RemoveAt(0);
                // Делим первое число на второе, результат(одна цифра) вставляем в начало ответа.
                for (int i = xn - 1; i >= 0; i--)
                {
                    b  = p * 10 + x.num[i];
                    p  = b % y;
                    b /= y;
                    a.num.Insert(0, b);
                }
                // Записываем эспоненту ответа.
                a.exp = x.exp;
                // Если остался перенос, считаем до 15 знака после запятой.
                if (p > 0)
                {
                    while ((a.exp < x.maxexp) && (p != 0))
                    {
                        b  = p * 10;
                        p  = b % y;
                        b /= y;
                        a.num.Insert(0, b);
                        a.exp++;
                    }
                }
            }
            // Если во втором числе больше 1 цифры, делаем его длинным и считаем частное длинных чисел.
            else
            {
                string s = Convert.ToString(y);
                x = new LongNumber(s);
                a.EqualTo(x1 / x);
            }
            // Удаляем лишние нули и возвращаем.
            a.RemoveZeros();
            return(a);
        }
Beispiel #18
0
        public static bool operator >(LongNumber x1, LongNumber y1)  // Перегрузка сравнения 1.
        {
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            // Переменная для ответа.
            bool b = false;

            // Если знак первого меньше, то ложь.
            if (x.sign < y.sign)
            {
                return(false);
            }
            // Если знак второго меньше - истина.
            else if (x.sign > y.sign)
            {
                return(true);
            }
            // Знаки равны, теперь если у первого длиннее целая часть - истина.
            if (x.num.Count - x.exp > y.num.Count - y.exp)
            {
                return(true);
            }
            // Если короче - ложь.
            else if (x.num.Count - x.exp < y.num.Count - y.exp)
            {
                return(false);
            }
            // Целые части одинаковой длины.
            else
            {
                // Приводим оба числа к одному количеству знаков, добавляя нули в более короткое.
                int c = Math.Abs(x.exp - y.exp);
                if (x.exp > y.exp)
                {
                    for (int i = 0; i < c; i++)
                    {
                        y.num.Insert(0, 0);
                    }
                }
                else if (x.exp < y.exp)
                {
                    for (int i = 0; i < c; i++)
                    {
                        x.num.Insert(0, 0);
                    }
                }
                // Перебираем все цифры.
                for (int i = 0; i < x.num.Count; i++)
                {
                    // Если цифра первого числа больше цифры того же разряда второго числа, флаг - истина.
                    if (x.num[i] > y.num[i])
                    {
                        b = true;
                    }
                    // Если меньше - ложь. Равенство не меняет флаг.
                    if (x.num[i] < y.num[i])
                    {
                        b = false;
                    }
                }
                // Возвращаем ответ.
                return(b);
            }
        }
Beispiel #19
0
        public static LongNumber operator +(LongNumber x1, LongNumber y1)  // Перегрузка оператора сложения.
        {
            // Создаём переменную для ответа.
            LongNumber a = new LongNumber();
            // Сохраняем входные переменные, т.к., возможно, будем их позже менять.
            LongNumber x = new LongNumber();

            x.EqualTo(x1);
            LongNumber y = new LongNumber();

            y.EqualTo(y1);
            // Запоминаем длины чисел.
            int xn = x.num.Count, yn = y.num.Count;

            // Проверяем равенство знаков.
            if (x.sign == y.sign)
            {
                // Переменные для текущего результата и переноса.
                int b = 0;
                int p = 0;
                // Удаляем все ячейки в переменной ответа.
                a.num.RemoveAt(0);
                // Разница в длинах дробных частей.
                int c = Math.Abs(x.exp - y.exp);
                // Сравниваем длины дробных частей.
                if (x.exp >= y.exp)
                {
                    // Если длиннее первое, переписываем более длинную часть в ответ.
                    for (int i = 0; i < c; i++)
                    {
                        a.num.Add(x.num[i]);
                    }
                    // Считаем сумму общей части, учитывая, что второе сдвинуто относительно первого
                    // для совпадения позиции запятой.
                    for (int i = c; i < Math.Min(xn, yn + c); i++)
                    {
                        b = x.num[i] + y.num[i - c] + p;
                        a.num.Add(b % 10);
                        p = b / 10;
                    }
                    // Сравниваем длины чисел.
                    if (yn + c >= xn)
                    {
                        // Если второе длиннее, переписываем его в ответ, учитывая перенос.
                        for (int i = xn; i < yn + c; i++)
                        {
                            b = y.num[i - c] + p;
                            a.num.Add(b % 10);
                            p = b / 10;
                        }
                    }
                    else
                    {
                        // Если первое длиннее, переписываем его в ответ, учитывая перенос.
                        for (int i = yn + c; i < xn; i++)
                        {
                            b = x.num[i] + p;
                            a.num.Add(b % 10);
                            p = b / 10;
                        }
                    }
                    // Записываем экспоненту в ответ.
                    a.exp = x.exp;
                }
                else
                {
                    // Если длиннее второе, переписываем более длинную часть в ответ.
                    for (int i = 0; i < c; i++)
                    {
                        a.num.Add(y.num[i]);
                    }
                    // Считаем сумму общей части.
                    for (int i = c; i < Math.Min(xn + c, yn); i++)
                    {
                        b = x.num[i - c] + y.num[i] + p;
                        a.num.Add(b % 10);
                        p = b / 10;
                    }
                    // Сравниваем длины чисел.
                    if (yn >= xn + c)
                    {
                        // Если длиннее второе , переписываем его в ответ, учитывая перенос.
                        for (int i = xn + c; i < yn; i++)
                        {
                            b = y.num[i] + p;
                            a.num.Add(b % 10);
                            p = b / 10;
                        }
                    }
                    else
                    {
                        // Если длиннее первое, переписываем его в ответ, учитывая перенос.
                        for (int i = yn; i < xn + c; i++)
                        {
                            b = x.num[i - c] + p;
                            a.num.Add(b % 10);
                            p = b / 10;
                        }
                    }
                    // Записываем экспоненту в ответ.
                    a.exp = y.exp;
                }
                // Записывем знак.
                a.sign = x.sign;
            }
            // Если знаки не равны, меняем один и считаем разность.
            else
            {
                y.sign *= -1;
                a.EqualTo(x - y);
            }
            // Удаляем лицние нули, если они есть.
            a.RemoveZeros();
            // Возвращаем ответ.
            return(a);
        }