32-битное int * 32-битное int = 64-битное int? - PullRequest
6 голосов
/ 19 апреля 2009

Другими словами, это работает как ожидалось?

int32 i = INT_MAX-1;
int64 j = i * i;

или мне нужно сначала преобразовать i в 64 бит?

Ответы [ 5 ]

17 голосов
/ 19 апреля 2009

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

(Если int64 на самом деле не является собственным типом int для вашей конкретной системы, что кажется маловероятным)

7 голосов
/ 19 апреля 2009

Это зависит от того, что такое int32 и int64.

Короче говоря, перед целыми арифметическими операциями все целые числа увеличиваются до размера не менее int (который может составлять 64 бита), а также до размера большего операнда для бинарных операторов, если он имеет больший ранг, чем int.

То, как используется результат выражения (независимо от того, хранится оно в более широком типе или нет), не имеет отношения к продвижению составных частей выражения.

3 голосов
/ 19 апреля 2009

Основной ответ: нет, он не будет делать то, что вы хотите.
Но он делает то, что ожидается.

Об математических операциях следует отметить две вещи:

  • Оба операнда будут одного типа.
  • Полученный тип будет таким же, как и у ввода.

Если компилятор отмечает несоответствие между операндами, он преобразует один из операндов так, чтобы оба соответствовали (см. Какие переменные мне следует вводить при выполнении математических операций в C / C ++? ). Примечание. Это делается независимо от того, что происходит с результатом.

0 голосов
/ 20 апреля 2009

См .: 14. Смешанное использование простых целочисленных типов и memsize-типов. http://www.viva64.com/art-1-2-599168895.html

0 голосов
/ 19 апреля 2009

Учитывая два числа a, b, и каждое число использует биты len_a и len_b.

Ваш выходной тип данных должен содержать как минимум: len_a и len_b бит.

В приведенном выше коде у вас есть два 31-битных числа (потому что INT_MAX - 1 = 0x7FFFFFFE использует 31 бит), и вам нужно будет типизировать один из них в int64_t, потому что он будет делать 32-битное умножение и переполнение, прежде чем он будет приведен к int64_t.


Количество битов, необходимых для умножения с фиксированной запятой:

len_output = howManyBits( a * b )
           = len_a + len_b

Краткий пример, демонстрирующий приведенное выше правило в действии:

a     = 7
len_a = 3

b     = 7
len_b = 3

c = a * b
  = 49 ( decimal )
  = 0x31 ( hex )

len_c = howManyBits( 0x31 ) 
      = 6

Вы можете написать функцию для подсчета битов. Или, если вам нужна быстрая проверка работоспособности, чтобы подтвердить это, используйте что-то вроде Windows Calc, которое преобразует число в двоичную форму и подсчитывает используемые биты.

...