Пример #1
0
 public BigInt(BigInt a)
 {
     sign   = a.sign;
     module = new Queue <int>(a.module);
 }
Пример #2
0
        public static BigInt operator -(BigInt left, BigInt right)
        {
            BigInt tmp = new BigInt(right);

            if (tmp.sign == Sign.minus)
            {
                tmp.sign = Sign.plus;                 // x-(-y) преобразуем в x+y и передаем в метод суммы
            }
            else
            {
                tmp.sign = Sign.minus;
            }

            if (left.sign == tmp.sign)
            {
                return(left + tmp);       // –x-y преобразуем в –(x+y) передаем методу суммы
            }
            BigInt rasn   = new BigInt(); // сюда записывается разность
            int    digit  = 0;            // 1 для вычитания из старшего разряда
            int    marker = 0;            // для вычисления позиции, с которой остаются разряды только одного числа

            if (left >= right)            // ставим большее число сверху в столбике
            {
                for (int i = left.module.Count() - 1, j = right.module.Count() - 1; j >= 0; i--, j--)
                {
                    if ((left.module.ElementAt(i) - right.module.ElementAt(j) - digit) >= 0)                     // поразрядно вычитаем
                    {
                        rasn.module.Enqueue(left.module.ElementAt(i) - right.module.ElementAt(j) - digit);
                        digit = 0;
                    }
                    else
                    {
                        rasn.module.Enqueue(left.module.ElementAt(i) - right.module.ElementAt(j) + 10 - digit);                         // заимствуем 1 из старшего разряда
                        digit = 1;
                    }

                    marker = i;
                }

                for (int i = marker - 1; i >= 0; i--)                 // добиваем числами оставшихся разрядов, учитывая -1
                {
                    rasn.module.Enqueue(Math.Abs((left.module.ElementAt(i) - digit + 10) % 10));

                    if ((digit == 1) && (left.module.ElementAt(i) - digit) < 0)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;
                    }
                }
                rasn.sign = left.sign;
            }
            else
            {
                for (int i = right.module.Count() - 1, j = left.module.Count() - 1; j >= 0; i--, j--)
                {
                    if ((right.module.ElementAt(i) - left.module.ElementAt(j) - digit) >= 0)
                    {
                        rasn.module.Enqueue(right.module.ElementAt(i) - left.module.ElementAt(j) - digit);
                        digit = 0;
                    }
                    else
                    {
                        rasn.module.Enqueue(right.module.ElementAt(i) - left.module.ElementAt(j) + 10 - digit);
                        digit = 1;
                    }

                    marker = i;
                }

                for (int i = marker - 1; i >= 0; i--)
                {
                    rasn.module.Enqueue(Math.Abs((right.module.ElementAt(i) - digit + 10) % 10));

                    if ((digit == 1) && (right.module.ElementAt(i) - digit) < 0)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;
                    }
                }

                rasn.sign = tmp.sign;
            }

            rasn.module = new Queue <int>(rasn.module.Reverse());
            return(rasn.UnNull());
        }
Пример #3
0
        static BigInt Division(BigInt divident, BigInt _divider, DivisionMode mode)
        {
            BigInt divider = new BigInt(_divider);
            //test
            DateTime  timestamp1;
            DateTime  timestamp2;
            Stopwatch fastTime2 = new Stopwatch();

            fastTime2.Start();
            timestamp1 = DateTime.Now;
            //endtest
            divider.sign = Sign.plus;
            BigInt quotient = new BigInt();
            BigInt rest     = new BigInt();
            BigInt tmp      = new BigInt();

            tmp.module = divider.module;
            for (int i = 0; i < divident.module.Count(); i++)
            {
                rest.module.Enqueue(divident.module.ElementAt(i));                 // промежуточный остаток
                rest.UnNull();
                // пока промежуточный остаток меньше делителя, пишем к частному 0
                if (rest >= divider)
                {
                    for (int j = 1; j <= 10; j++)               // цикл, формирующий цифры частного
                    {
                        if (rest < tmp)                         // промежуточный остаток меньше делителя*j
                        {
                            quotient.module.Enqueue(j - 1);
                            rest      -= (tmp - divider);
                            tmp.module = divider.module;
                            break;
                        }
                        if (rest == tmp)                         // промежуточный остаток кратный делителю
                        {
                            quotient.module.Enqueue(j);
                            rest.module.Clear();
                            tmp.module = divider.module;
                            break;
                        }
                        tmp += divider;                         // прибавляем сам делитель, пока не станет больше остатка
                    }
                }
                else
                {
                    quotient.module.Enqueue(0);
                }
            }             // цифры делимого заканчиваются и остаток меньше делимого, цикл завершается

            if (divident.sign != _divider.sign)
            {
                quotient.sign = Sign.minus;
            }

            if (rest.module.Count() == 0)
            {
                rest.module.Enqueue(0);
            }
            if (quotient.module.Count() == 0)
            {
                quotient.module.Enqueue(0);
            }

            timestamp2 = DateTime.Now;
            fastTime2.Stop();

            if (mode == DivisionMode.quotient)
            {
                return(quotient);
            }
            else if (mode == DivisionMode.rest)
            {
                return(rest);
            }
            //test
            else
            {
                rest.time     = (timestamp2.Ticks - timestamp1.Ticks);
                rest.fastTime = fastTime2.ElapsedTicks;
                return(rest);
            }
            //endtest
        }
Пример #4
0
        public static BigInt operator +(BigInt left, BigInt right)
        {
            if (left.sign != right.sign)             // если разные знаки, то отправляем на метод разность
            {
                if (left.sign == Sign.minus)         // заменяем –x+y на y-x
                {
                    BigInt tmp = new BigInt(left);
                    tmp.sign = Sign.plus;
                    return(right - tmp);
                }
                else                 // заменяем x+-y на x-y
                {
                    BigInt tmp = new BigInt(right);
                    right.sign = Sign.plus;
                    return(left - tmp);
                }
            }

            BigInt summa  = new BigInt();                                                             // сюда записывается результат
            int    digit  = 0;                                                                        // 1 для добавления к старшему разряду
            int    marker = 0;                                                                        // для вычисления позиции, с которой остаются разряды только одного числа

            if (left.module.Count() >= right.module.Count())                                          // ставим большее число на первое место
            {
                for (int i = left.module.Count() - 1, j = right.module.Count() - 1; j >= 0; i--, j--) // начиная с первых разрядов складываем числа
                {
                    summa.module.Enqueue((left.module.ElementAt(i) + right.module.ElementAt(j) + digit) % 10);

                    if ((left.module.ElementAt(i) + right.module.ElementAt(j) + digit) >= 10)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;                         // прибавляем 1 на следующем шаге, если сумма больше 10
                    }
                    marker = i;
                }

                for (int i = marker - 1; i >= 0; i--)                 // начиная с позиции метки добиваем цифрами из большего числа, учитывая возможное прибавление 1
                {
                    summa.module.Enqueue((left.module.ElementAt(i) + digit) % 10);

                    if ((left.module.ElementAt(i) + digit) == 10)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;
                    }
                }

                if (digit == 1)
                {
                    summa.module.Enqueue(1);                     // срабатывает в случае когда увеличивается разряд, например 99+1=100
                }
            }
            else
            {
                for (int i = right.module.Count() - 1, j = left.module.Count() - 1; j >= 0; i--, j--)
                {
                    summa.module.Enqueue((right.module.ElementAt(i) + left.module.ElementAt(j) + digit) % 10);

                    if ((right.module.ElementAt(i) + left.module.ElementAt(j) + digit) >= 10)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;
                    }

                    marker = i;
                }

                for (int i = marker - 1; i >= 0; i--)
                {
                    summa.module.Enqueue((right.module.ElementAt(i) + digit) % 10);

                    if ((right.module.ElementAt(i) + digit) == 10)
                    {
                        digit = 1;
                    }
                    else
                    {
                        digit = 0;
                    }
                }

                if (digit == 1)
                {
                    summa.module.Enqueue(1);
                }
            }

            summa.sign   = left.sign;
            summa.module = new Queue <int>(summa.module.Reverse());

            return(summa);
        }