Пример #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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
            }
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }