public BigInt(BigInt a) { sign = a.sign; module = new Queue <int>(a.module); }
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()); }
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 }
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); }