С.И.Хашин
В этом модуле реализованы целые 16-байтовые беззнаковые числа.
Работает только для _WIN64, так как использует соответствующие встроенные ассемблерные функции из intrin.h!
Замечание. Деление (пока) реализовано очень медленно! Если важна скорость, используйте GMP или MPIR! Но для несложных приложений, типа "задачи 3n+1" предлагаемый модуль вполне подойдет.
Наименьшее число - 0, наибольшее: 340282366920938463463374607431768211455=2128-1 (≈3.4 *1038)
Из не совсем очевидных операций отметим:
char *toString(); char *toStringH(); // hexЭти две функции ВСЕГДА возвращают один и тот же указатель. Поэтому нельзя, например, писать так:
printf("x=%s, y=%s\n", x.toString(), y.toString()); // ОШИБКА!Правильно написать так:
printf("x=%s, ", x.toString()); printf("y=%s\n", y.toString());
Так менее удобно, но зато не надо заботиться об освобождении памяти.
Далее,
int shift2s(); // делим на 2 пока не будет нечетное int log2(); // номер старшего бита 0..127 void pow2(int n); // this = 2^n void pow(u64 f, int n); // this = f^nНапример, в результаты выполнения
u128 x; x.pow(10, 38); printf("x=%s, log=%d\n", x.toString(), x.log2()); int k = x.shift2s(); printf("x=%s, k=%d\n", x.toString(), k);Получим:
x=100000000000000000000000000000000000000, log=126 x=363797880709171295166015625, k=38Примеры:
u128 x = 0xffffffffffffffffLL; printf(" %s \n", x.toString()); u128 y(0, 1); printf(" %s \n", y.toString()); ++x; printf(" %s \n", x.toString()); x -= 2; printf(" %s \n", x.toString()); --x; printf(" %s \n", x.toString()); x += 3; if (x == y) printf("equal\n"); x -= y; printf(" %s \n", x.toString()); x.pow(10, 38); x += 17; y.pow(10, 28); u128 r, d; x.div(y, d, r); printf("x =%s, ", x.toString()); printf("y =%s,\n", y.toString()); printf("d =%s, ", d.toString()); printf("r =%s\n", r.toString());Обратите внимание, не x++, x--, а ++x, --x.