Как правильно умножить два длинных длинных целых? - PullRequest
0 голосов
/ 22 августа 2010

Я хочу умножить длинные числа, которые даны в 2 ^ 32 основе.Я уже придумал хороший алгоритм для этого, но, к сожалению, я застрял.Ситуация, в которой я застрял, заключается в том, как я умножаю два длинных целых числа и представляю их на основе 2 ^ 32.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef unsigned int uint32;
typedef unsigned long long uint64;
int main(int argc, char* argv[] )
{

  uint64 a = (uint64)ULONG_MAX;
  printf("%llu\n", a);
  uint64 b = (uint64)ULONG_MAX;  
  printf("%llu\n", b);  
  uint64 c = (uint64)(a*b);

  printf("%llu\n", c);  // prints 1. that would be to lower 32 bits of the results. the upper half is 0xFFFFFFFE

  printf("%llu\n", ULLONG_MAX);
  system("pause");
}

Почему ULLONG_MAX совпадает с ULONG_MAX?Согласно http://en.wikipedia.org/wiki/Limits.h#Member_constants это должно быть 18,446,744,073,709,551,615 I

Как вы можете видеть из моих комментариев, я хочу получить результат умножения в двух uint32.Нижняя половина будет 0x1, а верхняя половина 0xFFFFFFFE.Как я могу получить эти значения?

(я нашел этот вопрос на SO, но в моей ситуации он бесполезен, потому что ответы на мои идеи аналогичны: Умножение двух длинных длинных целых C )

Редактировать: Моя система - Windows XP 32 Bit.Я использую gcc 3.4.2 (mingw-special)

Вывод, который я получаю при запуске кода:

4294967295
4294967295
1
4294967295

Edit2:

  printf("%i\n", sizeof(unsigned long));
  printf("%i\n", sizeof(unsigned long long)); 

возврат

4
8

Редактировать 3: Благодаря Петешу мне удалось найти решение:

  printf("%lu\n", c & 0xFFFFFFFF);
  printf("%lu\n", (c >> 32));

Ответы [ 2 ]

5 голосов
/ 22 августа 2010

Подсказка в системе («пауза») - вы на windows?Для печати long long с использованием Microsoft Visual C Runtime требуется использовать «% I64u» (это заглавная буква i).

Это основано на вопросе SO Как вы печатаете long unsigned int int (форматспецификатор для unsigned long long int)?

3 голосов
/ 22 августа 2010

Не знаю, почему вы получаете эти результаты с вашим (неуказанным) компилятором, но gcc в Ubuntu 10 дает:

4294967295
4294967295
18446744065119617025
18446744073709551615

с последними двумя 0xfffffffe00000001 и (2 64 -1) соответственно, по вашему желанию.

Так что, возможно, стоит подумать о переходе на более современный компилятор.Возможно, вы используете компилятор до C99.

Просто из интереса, что sizeof (unsigned long) и sizeof (unsigned long long) дают вам в вашей системе.Это будет иметь большое значение для объяснения вашей проблемы.


Несколько других вещей, которые нужно проверить, поскольку ваши sizeof s, похоже, указывают на то, что сами типы данных в порядке (хотя они могут не решить проблему- они были найдены с помощью довольно мелкого веб-поиска ):

  • Попробуйте использовать "%I64u" в качестве строки формата вместо "%llu".Если MinGW использует библиотеки MSVCRT, это может потребоваться для реальной поддержки 64-битных printf.
  • Убедитесь, что вы компилируете с -std=c99.
...