unsigned long long x;
unsigned int y, z;
x = y*z;
На оценку выражения y*z
не влияет контекст, в котором оно появляется. Он умножает два значения unsigned int
, давая результат unsigned int
. Если математический результат не может быть представлен в виде значения unsigned int
, результат будет зациклен. Затем присваивание неявно преобразует (возможно, усеченный) результат из unsigned int
в unsigned long long
.
Если вы хотите, чтобы умножение давало результат unsigned long long
, вам нужно явно преобразовать один или оба операнда:
x = (unsigned long long)y * z;
или, чтобы быть более явным:
x = (unsigned long long)y * (unsigned long long)z;
Оператор умножения *
языка C применяется только к двум операндам одного типа. Из-за этого, когда вы даете ему операнды разных типов, они преобразуются в какой-то общий тип до того, как будет выполнено умножение. Правила могут быть немного сложными, когда вы смешиваете типы со знаком и без знака, но в этом случае, если вы умножаете unsigned long long
на unsigned int
, операнд unsigned int
повышается до unsigned long long
.
Если unsigned long long
по крайней мере в два раза шире unsigned int
, как в большинстве систем, то результат не будет переполняться или циклически повторяться, потому что, например, 64-битный unsigned long long
может содержать результат умножение любых двух 32-битных значений unsigned int
. Но если вы работаете в системе, где, например, int
и long long
имеют разрядность 64 бита, вы все равно можете использовать обход overflow, что даст вам результат в x
, который не равен математическому произведению y
и z
.
person
Keith Thompson
schedule
10.03.2014
y
иz
оба являютсяunsigned int
. - person Keith Thompson   schedule 11.03.2014