В текущем стандартном драфте C ++ оператор левого сдвига определяется следующим образом [expr.shift] :
Значение E1 << E2
равно , уникальное значение соответствует E1×2^E2
по модулю 2^N
, где N
- ширина типа результата.
Рассмотрим int E1 = 2^31-1 = 2'147'483'647
, E2 = 1
и int
, имеющие 32 бита. Тогда существует бесконечное число чисел, равных E1×2^E2 = 4'294'967'294
по модулю 2^N = 2^32
, а именно, все числа 4'294'967'294 + k×2^32
, где k
- произвольное целое число. Примеры: 4'294'967'294
(k=0
) или -2
(k=-1
).
Я не понимаю, что Стандарт подразумевает под уникальным значением из этих чисел. Означает ли это уникальное значение, которое может быть представлено результирующим типом данных ? Тогда, я полагаю, результат определяется как -2
. Правильно ли это истолковано?
До C ++ 20 определение было другим, и это могло привести к неопределенному поведению. Я полагаю, что изменение связано с обязательным представлением двух чисел с отрицательным знаком.
Фактически, теперь больше не требуется, чтобы E2
был неотрицательным. Поэтому кажется, что -1 << 1
определяется как -2
. Это тоже правильно?