Умножение char и int вместе в C часть 2 - PullRequest
0 голосов
/ 19 апреля 2010

Если я сделаю следующее:

int c0 = CHAR_MAX; //8 bit
int c1 = CHAR_MAX; //8-bit
int i = c0*c1; //store in 32-bit variable
printf("%d\n", i); //prints 16129

Мы видим, что нет проблем с умножением 8-битных чисел и получением 32-битного вывода.

Однако, если я сделаю

int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long int ll = i0*i1; //store in 64-bit variable
printf("%lld\n", ll); //prints 1..overflow!!

В этом случае две 32-битные переменные были умножены вместе, переполнены, а затем присвоены 64-битной переменной.

Так почему же это переполнение произошло при умножении целых чисел, а не на символы? Это зависит от размера слова по умолчанию моей машины? (32-бит)

Ответы [ 3 ]

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

Вы должны изменить свой второй пример кода как

int i0 = INT_MAX; //32-bit
int i1 = INT_MAX; //32 bit variable
long long ll = ((long long)i0)*i1; //compute and store in 64-bit variable
printf("%lld\n", ll);

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

В первом примере int достаточно большой, чтобы вместить результат умножения char s, поэтому переполнения нет.

В качестве дополнительного примечания называть вашу переменную ll не рекомендуется, поскольку очень трудно провести различие между цифрой «1» и строчной буквой «l».

1 голос
/ 19 апреля 2010

В вашем объяснении происходящего есть логическая ошибка.

По крайней мере, в системах Linux CHAR_MAX определенно не является 8-битным числом.Это (более или менее) простое определение препроцессора, например:

#  define SCHAR_MAX     127

/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#  define UCHAR_MAX     255

/* Minimum and maximum values a `char' can hold.  */
#  ifdef __CHAR_UNSIGNED__
#   define CHAR_MIN     0
#   define CHAR_MAX     UCHAR_MAX
#  else
#   define CHAR_MIN     SCHAR_MIN
#   define CHAR_MAX     SCHAR_MAX
#  endif

Итак, для системы со знаком char s действуют две последние строки, что означает, что когда вы пишете CHAR_MAXв вашем коде компилятор видит обычное 127, которое имеет тип int.

Это означает, что умножение CHAR_MAX * CHAR_MAX происходит с точностью int.

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

Как работает Typecast ...


Если не указано явное приведение типа, любое выражение преобразуется с точностью до самой высокой переменной / постоянной точности.

Как указал Питер, использование явного типа приведено в выражении для усиления более высокой точности.

ПРИМЕЧАНИЕ: Я не получил "long long int" часть. Может быть, это было долго раз с тех пор, как я его увидел ...; -)

  • Действительно ли long long int действительно объявляет 64-битное int ??

какой компилятор U использует ??

...