Что означает «производить отрицательные нули» в системе, которая его не поддерживает? - PullRequest
19 голосов
/ 07 марта 2019

C17 6.2.6.2/4 говорит:

Если реализация не поддерживает отрицательные нули, поведение операторов &, |, ^, ~, << и >> с операндамичто приведет к такому значению не определено.

Если у меня есть система дополнения 2, она не поддерживает отрицательные нули.И он всегда использует все возможные комбинации двоичного числа, чтобы выразить значение.Поэтому невозможно получить отрицательный ноль независимо от того, какая битовая операция используется.Так в чем же смысл этого текста?

Я предполагаю, что эта часть относится к системам с дополнением 1 или величиной со знаком, которые не поддерживают отрицательные нули, но вместо этого используют бит дополнения или представление прерывания.Это правильно?

Ответы [ 2 ]

14 голосов
/ 07 марта 2019

Да, я думаю, что ваша интерпретация верна. В дополнение к двум, это не операции, которые могли бы генерировать отрицательный ноль, потому что концепция здесь не существует: любое значение, для которого установлен бит знака, обязательно меньше 0.

Кстати: очень вероятно, что экзотические символьные представления будут удалены из C2x, поэтому все это исчезнет.

12 голосов
/ 07 марта 2019

Ваша интерпретация верна.

Переход к пункту 2 пункта 6.2.6.2:

.

Для целочисленных типов со знаком - биты объекта представление должно быть разделено на три группы: биты значения, биты заполнения и бит знака. Там не должно быть никаких биты заполнения; знаковый символ не должен иметь никаких битов заполнения. Должен быть ровно один знаковый бит. Каждый бит, который является бит значения должен иметь то же значение, что и тот же бит в представление объекта соответствующего типа без знака (если есть M битов значения в типе со знаком и N в типе без знака, тогда M ≤ N ). Если знаковый бит равен нулю, он не должен влиять на результирующий значение. Если бит знака равен единице, значение должно быть изменено одним из следующих способов:

  • соответствующее значение со знаковым битом 0 отменяется (знак и величина);
  • знаковый бит имеет значение - (2 M ) (дополнение к двум);
  • знаковый бит имеет значение - (2 M - 1) (дополняет единицу).

То, что применяется, определяется реализацией, , как и значение со знаком бит 1 и все биты значения ноль (для первого два) или со знаковым битом и всеми значениями битов 1 (для единиц дополнение), представление ловушки или нормальное значение. В случай знака и величины и их дополнения, если это представление является нормальным значением, оно называется отрицательным нулем.

Это означает, что реализация, использующая либо дополнение, либо знак и величину, имеет для данного целочисленного типа размера конкретное представление, которое должно быть либо отрицательным нулем, либо представлением ловушки. Затем выбор зависит от реализации.

В качестве примера предположим, что система имеет представление знака и величины и 32-битное int без заполнения. Тогда представление, которое будет отрицательным нулем, если оно поддерживается, будет 0x80000000.

Теперь предположим, что выполняются следующие операции:

 int x = 0x7fffffff;
 x = ~x;

Если реализация поддерживает отрицательный ноль, оператор ~ сгенерирует -0 в качестве результата и сохранит его в x. Если это не так, он создает представление ловушки и вызывает неопределенное поведение в соответствии с пунктом 4.

...