2015-04-03 2 views
0

Я перехожу к C++ Primer 5th Edition и сейчас выполняю подписанный/неподписанный раздел. Быстрый вопрос у меня есть, когда есть наматывается вокруг, скажем, в этом блоке кода:Оберните вокруг диапазона unsigned int в C++?

unsigned u = 10; 
int i = -42; 
std::cout << i + i << std::endl; // prints -84 
std::cout << u + i << std::endl; // if 32-bit ints, prints 4294967264 

Я думал, что диапазон макс был 4294967295 с 0 подсчетом, поэтому мне было интересно, почему обертка Похоже, что в этой задаче делается 4294967296.

+0

Полезный совет: диапазон подписанного числа бит-бит 2-го разряда [- (2^(b-1)), (2^(b-1)) - 1]. Обратите внимание, что это не симметрично около 0. – wjl

+0

Как вы думаете, '0u - 1' должно быть? –

+0

'UINT_MAX' гарантированно будет * не менее *' 65535'. Обычно это '4294967295' в большинстве современных реализаций. –

ответ

1

Когда значение вне диапазона преобразуется в неподписанный тип, результатом является остаток от него по модулю количества значений, которые может удерживать целевой тип без знака. Например, результат n, преобразованный в unsigned char, равен n % 256, поскольку unsigned char может хранить значения 0 до 255.

Это похоже на ваш пример, wrap-around выполняется с использованием 4294967296, числа значений, которое может содержать 32-разрядное целое число без знака.

2

Беззнаковая арифметика по модулю (максимальное значение типа плюс 1).

Если максимальное значение без знака является 4294967295 (2^32 - 1), то результат будет математически равен (10-42) по модулю 4294967296, которая равна 10-42 + 4294967296 4294967264 т.е.

1

Учитывая unsigned int, который является 32 бит, вы правы, что диапазон [0, 4294967295].

Поэтому -1 - 4294967295. Что логически эквивалентно 4294967296 - 1, которое должно объяснить поведение, которое вы видите.

Смежные вопросы