Попытка понять подписанное целочисленное правило преобразования из стандарта - PullRequest
1 голос
/ 11 июля 2019

Попытка понять синтаксис в стандарте:

6.3.1.3 Целые числа со знаком и без знака

  1. Когда значение с целочисленным типом преобразуется в другой целочисленный тип, другойчем _Bool, если значение может быть представлено новым типом, оно не изменяется.
  2. В противном случае, если новый тип является беззнаковым, значение преобразуется многократно , добавляя или вычитая на единицу больше максимального значения, которое может быть представлено в новом типе , пока значение не будет вАссортимент нового типа.
  3. В противном случае новый тип подписывается и значение не может быть представлено в нем;либо результат определяется реализацией, либо генерируется определяемый реализацией сигнал.

Примечание раздел 2, что означает, что приведение int к unsigned int выполняется путем добавления UINT_MAX + 1 до значения в int.

Что обсуждается, например, в этих двух обсуждениях:

Может ли компилятор C изменить представление битов при приведении знака к unsigned?

Подписано на беззнаковое преобразование в C - всегда ли это безопасно?

Ну, так как UINT_MAX + 1 всегда обещают быть нулевым (* 1036)* section 2 можно прочитать как:

В противном случае, если новый тип не подписан, значение преобразуется путем многократного добавления или вычитания ноль , пока значение не будет вдиапазон нового типа.

Что не имеет смысла для меня, так как добавление нуля ничего не меняет. Моя английская интерпретация нарушена? Чего мне здесь не хватает?

Ответы [ 2 ]

4 голосов
/ 11 июля 2019
В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного сложения или вычитания более одного максимального значения, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа.

В этом контексте «сложение или вычитание» относится к работе с математическим значением , а не к значению C с использованием операторов + и - языка C.

Например, если начальное значение равно -42, а UINT_MAX равно 65535, то результат равен -42 + 65536 или 65494.Это математическое значение находится в диапазоне unsigned int, что дает значение C 65494U.

Это правда, что результат вычисления выражения C UINT_MAX + 1 равен нулю.Вот почему в стандарте говорится «на единицу больше, чем максимальное значение, которое может быть представлено в новом типе», а не UINT_MAX + 1.(Правда, это можно было бы сформулировать немного более четко.)

2 голосов
/ 11 июля 2019

Во-первых, в выдержке из стандарта C отсутствуют два важных слова, которые нужно прочитать в нем

  • В противном случае, если новый тип является беззнаковым, значение преобразуется [, как если бы ], путем многократного добавления или вычитания на единицу больше максимального значения, которое может быть представлено в новом типе, пока значение не будет в ассортимент нового типа.

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

еще одну часть можно только понимать как значение, которое не , представимое в беззнаковом типе, в противном случае оно не будет еще один , то есть >. Формулировку можно сопоставить с + 1, что является неоднозначным.

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

...