Ответ, который вы ищете, не помещается в 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?
Но это сработало для меняon:
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, чтобы сделать его более общим, но, вероятно, не существует супер-удивительного способа сделать это везде.