Beispiel #1
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);
        }