Итак мы подошли к первой операции, реализацию которой можно считать не такой тривиальной, как в предыдущих случаях:
- BigInt operator * (const BigInt &a, const BigInt &b)
- {
- BigInt res;
- for (int i=0;i<a.amount;i++)
- {
- int r = 0;
- for (int j=0;j<b.amount | r;j++)
- {
- res.digits[i+j] += a.digits[i] * b.digits[j] + r;
- r = res.digits[i+j] / osn;
- res.digits[i+j] -= r*osn;
- }
- }
- int pos = a.amount + b.amount;
- while (pos>0 && !res.digits[pos])
- pos--;
- res.amount = pos + 1;
- return res;
- }
* This source code was highlighted with Source Code Highlighter.
Обратим внимание на строчку 11. Т.к. алгоритм квадратичный, то избежание использования операции взятия остатка от деления(%) дает прирост в скорости, более ощутимый, чем для линейных алгоритмов.
почему то на 9ой строке ошибка вылезает
ОтветитьУдалитьа у меня не вылазеет =). Покажите код целиком.
ОтветитьУдалитьОбъясните, для чего в этой строчке
ОтветитьУдалитьj<b.amount | r
нужно побитовое "ИЛИ"?
На самом деле здесь можно использовать как логическое или (||), так и побитовое(|). Логика от этого не меняется. Цикл в строке 7 повторяется до тех пор пока имеются необработанные разряды в числе b, либо до тех пор пока имеется перенос(r).
ОтветитьУдалитьХм, так значит приоритет операций такой, что сначала выполняется сравнение "меньше", а потом логическая операция. Это интересно, а я наоборот думал, что сначала выполнится побитовое "ИЛИ" и никак не мог понять, что получится
ОтветитьУдалитьВ любом случае если использовать побитовое или логическое ИЛИ, то оно всегда выполнится после операции МЕНЬШЕ(см. http://do.rksi.ru/library/courses/demo/t3_1p-1.gif). Возможно логическое ИЛИ здесь было бы более уместным, но я думаю уже все стало понятно, поэтому менять в реализации ничего не буду
УдалитьЕсли я не ошибаюсь, то оно верно работает только при a>b;
ОтветитьУдалитьКонтр пример к решению 9 70 выдает 63
Я думаю все написано правильно. У вас скорее всего некорректно работает ввод или вывод длинных чисел. Если вы считаете иначе, тогда присылайте ссылочку на ваш код(http://everfall.com/paste) и мы еще раз обсудим ваш комментарий
УдалитьА как насчет использования алгоритма Карацубы-Виноградова? Это будет О(n^Log1,6).
ОтветитьУдалитьВесь цикл статей на длинную арифметику на данный момент имеет вводный характер и ориентирован в первую очередь на понимание и реализацию. Быстрые алгоритмы надеюсь рассмотрим чуть позже.
УдалитьМне известен алгоритм Карацубы, который работает со сложностью O(N^log2(3)) = O(N^1.6). Дайте ссылку на упомянутый вами алгоритм.
res.digits необходимо проинициализировать нулями, иначе в 9 строке плюсовать будет вникуда!
ОтветитьУдалитьres.digits Обнулен в конструкторе
Удалить