С.И.Хашин
В этом модуле реализованы целые 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.