0x7FFFFFFF
требует 32 бита.Это может быть выражено как целое число без знака всего в 31 бите:
111 1111 1111 1111 1111 1111 1111 1111
, но если мы интерпретируем это как целое число со знаком, используя дополнение к двум, то ведущий 1
будет указывать, чтоэто отрицательно.Таким образом, мы должны добавить начальный 0
:
0 111 1111 1111 1111 1111 1111 1111 1111
, который затем делает его 32-битным.
Что касается того, что вам нужно изменить - ваша текущая программа на самом деле имеет неопределенное поведение.Если 0x7FFFFFFF
(2 31 -1) является максимально допустимым целочисленным значением, тогда 0x7FFFFFFF + 1
не может быть вычислено.Это может привести к -2 32 , но нет абсолютно никакой гарантии: стандарт позволяет компиляторам делать абсолютно все в этом случае, а реальные компиляторы действительно выполняют оптимизацию, которая может привести к шокирующим последствиям.результаты, когда вы нарушаете это требование.Точно так же нет конкретной гарантии того, что будет означать ... >> 1
, если ...
отрицательно, хотя в этом случае компиляторы обязаны, по крайней мере, выбрать конкретное поведение и задокументировать его.(Большинство компиляторов предпочитают создавать другое отрицательное число, копируя самый левый бит 1
, но это не гарантируется.)
Так что действительно единственное надежное исправление:
- переписать ваш код в целом, используя алгоритм, который не имеет этих проблем;или
- , чтобы специально проверить случай, когда
x
равен 0x7FFFFFFF
(возвращает жестко закодированный 32
), и случай, когда x
отрицателен (заменив его на ~x
, то есть -(x+1)
и продолжаем как обычно).