Вычисление остатка от суммы по большому модулю

Перенос при сложении всегда равен 0 или 1. Перенос равен 1 тогда и только тогда, когда сумма получилось меньше первого слагаемого (или меньше либо равна первому слагаемому, если был перенос). Разумеется, можно сравнивать и со вторым слагаемым - они равнозначны.

Например, сложение

std::uint64_t a[4]

и

std::uint64_t b[4]

может выглядеть так

C++Выделить код

1
2
3
4
5
6

    std::uint64_t p, c;
 
    p = a[0]; a[0] += b[0]; c = a[0] < p;
    p = a[1]; a[1] += b[1] + c; c = c != 0 ? a[1] <= p : a[1] < p;
    p = a[2]; a[2] += b[2] + c; c = c != 0 ? a[2] <= p : a[2] < p;
    a[3] += b[3] + c;

Можно также использовать массив пред-максимального типа (то есть

std::uint32_t

), а сложение производить в рамках

std::uint64_t

. Тогда старшая половина результата натуральным образом будет содержать перенос. Но тогда понадобится 8 элементов и 8 сложений, вместо 4. Не знаю, будет ли это лучше...