Давайте представим число в двоичном формате и посмотрим, что делает левый сдвиг.
for example
if i = 5 // binary 101
i<<1 becomes 10 // binary 1010
i<<2 becomes 20 // binary 10100
and so on
Аналогично
if i = 1 // binary 1
i<<1 becomes 2 // binary 10
i<<2 becomes 4 // binary 100
i<<n becomes 2^n // binary 1000...n times
i<<30 becomes 2^30 // binary 1000000000000000000000000000000
Если вы заметите, что 2 ^ n потребует n + 1 бит хранить, что объясняет вашу первую ошибку. 2 ^ 32 потребуется 33 бита, а std int будет 32-битным, вы получите ошибку переполнения.
Теперь обратите внимание, что 2 ^ 30 занимает 31 бит, которые представляют собой количество битов, выделенных для представления значения int, поскольку 32-й бит является знаковым битом (чтобы различать guish между отрицательными и положительными числами).
Итак, когда вы делаете i << 31, старший разряд 1 перезаписывает бит знака, и мы получаем отрицательное значение. </p>
Отрицательные числа в c ++ представлены с использованием дополнения 2s. 2s дополнение к 2 ^ 31 для 32-битного значения -2147483648, это то, что вы видите.
Теперь я << 30, когда i == 1 равно 2 ^ 30 или 1073741824 </p>