В своих бесконечный поисках откопал на Википедии совсем не то, что искал, а именно — красивый алгоритм извлечения квадратного корня с остатком из длинных чисел. В вики как всегда алгоритм перепечатали из источника с ошибкой, и без всяких дополнительных разъяснений. Хорошо хоть ссылку на
оригинальную статью привели. Автор алгоритма, судя по статье, некий
Поль Зиммерманн, и почему-то он назвал свой алгоритм "
Квадратный корень Карацубы". Но да ладно.
Процедура алгоритма представляет собой следующее.
Вход: одно число
n.
Выход: два числа
s и
r, такие что

.
Шаги алгоритма:1) если число
n достаточно мало (влезает в 32 бита, например), то вычисляем величины

стандартными средствами и возвращаем результат.
2) представляем исходное число в виде

3) рекурсивно вызывая процедуру находим значения
s' и
r' для числа

(первая половина исходного числа)
4) находим частное
q и остаток
u от деления числа

на число

5) находим целую часть корня и остаток:

6) если остаток получился отрицательным (

), то делаем коррекцию:

7) возвращаем результат.
Замечания. Очевидно, что в качестве
b при вычислении на компьютере удобно брать степени двойки (или десятки, если работа идёт с числами в десятичном представлении). Не смотря на то, что в оригинале процедура расчёта рекурсивная, её можно свести к обычному циклу. Этому способствует то, что в теле процедуры есть только один самовызов. Так что остаётся только правильно подобрать последовательность чисел
b, чтобы идти от малых корней к большим, а не на оборот, как в рекурсии. Автор, видимо, вдохновлялся алгоритмом Карацубы с его "разделяй и властвуй". Но конкретно в случае вычисления корня "властвовать" нужно только над одной половинкой, так что нет необходимости городить рекурсию.
Алгоритм очень сильно перекликается с
методом Ньютона расчёта квадратного корня. Например, он так же удваивает число правильных разрядов с каждой "итерацией" (если идти из "дна" рекурсии "наружу"). А так же они оба используют деление больших чисел, что в обоих случаях является самой трудоёмкой операцией и определяет сложность алгоритма. Однако,
алгоритм Зиммерманна на каждой итерации выполняет деление не полноразрядных чисел, как метод Ньютона, а чисел экспоненциально убывающей длины (если идти снаружи в глубь рекурсии). Это даёт значительно более высокую производительность. Кроме того, за счёт правильного разбиения и за счёт подсчёта на каждом шаге ровно стольк
и бит, сколько требуется, алгоритм не имеет никаких проблем с зацикливанием или "переработкой", как метод Ньютона (когда, например, для окончания расчёта не хватило 1-2 верных бит, а следующая итерация "удваивает точность", давая очередные 200 или 200'000 бит).
В качестве иллюстрации можно посчитать целочисленный корень из числа

.
Сначала разбиение:

(

)

(

)

(

)

(

)
Корень из

равен

, остаток

Делим

на

, получаем

, остаток

Корень из

равен

, остаток

Делим

на

, получаем

, остаток

Корень из

равен

, остаток

Делим

на

, получаем

, остаток

Корень из

равен

, остаток

Делим

на

, получаем

, остаток

Корень из

равен

, остаток

Окончательный результат:

. Чудесным образом нигде не потребовалась коррекция.