Я пытался реализовать алгоритм умножения Карацубы на С++ для двух больших чисел одинаковой длины. Мой код работает правильно для меньших чисел, таких как 3456*1492, но не работает с большими числами, такими как 64-значные. Обычно он получает первые несколько цифр правильно, но после этого идет наперекосяк. Я использую библиотеку мультиточности Boost для обработки больших целых чисел.
Мой код выглядит следующим образом:
cpp_int karatsuba(cpp_int n1, cpp_int n2) {
if (n1 < 10 || n2 < 10) {
return n1 * n2;
}
int len = countDigits(n1);
cpp_int a = n1 / cpp_int(pow(10, len/2));
cpp_int b = n1 % cpp_int(pow(10, len/2));
cpp_int c = n2 / cpp_int(pow(10, len/2));
cpp_int d = n2 % cpp_int(pow(10, len/2));
cpp_int sub1 = karatsuba(a, c);
cpp_int sub2 = karatsuba(b, d);
cpp_int sub3 = karatsuba(a+b, c+d) - sub1 - sub2;
return sub1 * cpp_int(pow(10, len)) + sub3 * cpp_int(pow(10, len/2)) + sub2;
}
Я сравнил свой код с несколькими реализациями в Интернете и не смог найти существенных различий, которые могли бы повлиять на ответ. Возможно, есть проблема с точностью типа cpp_int
или проблема в моем коде?
Большое вам спасибо за вашу помощь!
double
, но я получаю те же проблемы сuint1024_t
. - person Arnav Garg   schedule 26.05.2020countDigits
многократно делится на 10, пока число не станет равным 0, и подсчитывает количество делений. Я протестировалcountDigits
, поэтому уверен, что проблема не в нем. - person Arnav Garg   schedule 26.05.2020pow
внутри умножения? это безумие и сводит на нет преимущества сложности Карацубы, поскольку pow - это более высокая операция (которая также использует умножение внутри, которое привело бы к переполнению стека, если бы ваш Карацуба использовался кстати.) и намного медленнее ... используйте мощность 2 базы для разделения и битовых операций (бит сдвиги, И маскировка...) вместо этого. Также см. Быстрое вычисление квадрата большого числа. - person Spektre   schedule 26.05.2020