Откуда диапазон значений, тоже понятно. Но что конкретно происходит при попытке выйти за этот диапазон?
Почему при вычислении степеней двойки в какой-то момент выводится минимальное значение, -32768, а затем - одни нули?
Точно понятно?
2^0 == 0b0000000_00000001 == 1 (16 младших разрядов)
...
2^14 == 0b01000000_00000000 == 16384 (16 младших разрядов)
...
2^15 - 1 == 0b01111111_11111111 == 32767 (16 младших разрядов)
2^15 == 0b100000_00000000 == -32768 (16 младших разрядов)
2^15 + 1 == 0b100000_00000001 == -32767 (16 младших разрядов)
...
2^16 - 1 == 0b11111111_11111111 == -1 (16 младших разрядов)
2^16 == 0b1_00000000_00000000 == 0 (16 младших разрядов)
2^16 + 1 == 0b1_00000000_00000001 == 1 (16 младших разрядов)
Что происходит при других операциях со слишком большими числами?
Неопределённое поведение, если тип значения знаковый. Компилятор может наоптимизировать что захочет.
Если тип значения беззнаковый -- результат обрезается по ширине типа данных результата.