Ответ, который вы ищете, не помещается в 64-битный unsigned long long
, который является нормальным размером на 64-битной платформе; любой избыток во время умножения переполняется и отбрасывается.
Более новые версии GCC поддерживают 128-битные целые числа на 64-битных машинах с __int128
(и unsigned __int128
), и это работает:
unsigned long long int x = 0x28B2D48D74212E4FULL;
unsigned long long int y = 0x6734B42C025D5CF7ULL;
unsigned __int128 xy = x * (unsigned __int128)y;
Обратите внимание, что вам нужно привести один из x
или y
к более широкому типу, чтобы умножение выполнялось в 128 битах; в противном случае это повышение до 128 не выполняется до тех пор, пока не будет выполнено (усеченное) 64-битное умножение.
Проблема в том, насколько я могу судить, у printf()
нет простого способа сделать это, так что вам придется немного повозиться.
Некоторое разумное обсуждение здесь: как напечатать номер __uint128_t с помощью gcc?
Но это сработало для меня на:
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)
#include <stdio.h>
int main()
{
unsigned long long int x = 0x28B2D48D74212E4F;
unsigned long long int y = 0x6734B42C025D5CF7;
unsigned __int128 xy = x * (unsigned __int128)y;
printf("Result = %016llx%016llx\n",
(unsigned long long)( xy >> 64),
(unsigned long long)( xy & 0xFFFFFFFFFFFFFFFFULL));
return 0;
Приведения внутри printf
важны: в противном случае сдвиг/маскирование выполняется в 128-битных скалярах, и эти 128 бит помещаются в стек, но тогда каждый %llx
ожидает 64 бита.
Обратите внимание, что все это полностью зависит от базовой платформы и не является переносимым; конечно, есть способ использовать различные #ifdefs и sizeofs, чтобы сделать его более общим, но, вероятно, нет супер крутого способа заставить это работать везде.
person
Steve Friedl
schedule
21.12.2019
unsigned long long int
, очевидно, является 64-битным числом. Проверьте еще разULLONG_MAX
, вы, вероятно, ошиблись. - person Martin Heralecký   schedule 22.12.2019unsigned long long
в любой системе, о которой я знаю, вы не можете сравнивать с ним, так как он переполняется в арифметике. - person UnholySheep   schedule 22.12.2019unsigned long long
будет 128-битным на вашей платформе? Что это будет за платформа? - person Steve Friedl   schedule 22.12.2019uintmax_t
; или что-то вроде__uint128
- person M.M   schedule 22.12.20191068547cd3052bbe5688de35695b1239
в качестве результата - person cheshire   schedule 22.12.2019__uint128
на вашей платформе, вы можете распечатать его как два 64-битных слова. - person KamilCuk   schedule 22.12.2019