Подтвердить что ты не робот

Каково поведение при преобразовании отрицательного значения с плавающей запятой в unsigned int?

Что произойдет, если отрицательное значение с плавающей запятой преобразуется в значение беззнакового целочисленного типа? Стандартные котировки будут оценены. Проблема, с которой я столкнулась, заключается в преобразовании в значения неподписанных интегральных типов из вариантаного класса, который содержит объект типа с плавающей запятой.

Пример:

unsigned i = -.1;
4b9b3361

Ответ 1

В случае, если отрицательное значение равно -1,0 или ниже, оно вызывает поведение undefined, так как интегральная часть не может быть представлена ​​беззнаковым числом. В противном случае (как в случае -0.1), если он может быть представлен целым типом, это четко определенное поведение. См. Стандарт C11, ISO 9899: 2011:

6.3.1.4

Когда конечное значение реального плавающего типа преобразуется в целое число типа, отличного от _Bool, дробная часть отбрасывается (т.е. значение усекается к нулю). Если значение интегральной части не может быть представлен целым типом, поведение undefined. 61)

И тогда есть ненормативная нотная нота, поясняющая приведенный выше текст:

61) Операция останова, выполняемая, когда значение целочисленного типа преобразуется в неподписанный тип, не нужно выполнять, когда значение реальный плавающий тип преобразуется в неподписанный тип. Таким образом, диапазон переносные реальные значения плавающего значения (-1, Utype_MAX + 1).

ISO/IEC 9899: 1999 (C99) содержит точно такой же текст.

Ответ 2

Это поведение undefined в C99, если число с плавающей запятой меньше или равно -1.0. Если он находится в диапазоне (-1,0, 0,0), результирующее значение будет равно 0.

Из C99, §6.3.1.4, пункт 1

Когда конечное значение реального плавающего типа преобразуется в целочисленный тип, отличный от _Bool, дробная часть отбрасывается (т.е. значение усекается к нулю). Если значение целой части не может быть представлено целым типом, то поведение undefined

Сноска 50 разъясняет поведение для диапазона (-1.0, 0.0).

Ответ 3

В вашем примере unsigned i = -.1; четко определен как C11, так и C99, а результат i == 0.

Цитата из N1570, 6.3.1.4 Реальное плавающее и целое число:

  • Когда конечное значение реального плавающего типа преобразуется в целочисленный тип, отличный от _Bool, дробная часть отбрасывается (т.е. значение усекается к нулю). Если значение интегральной части не может быть представлен целым типом, поведение undefined 0,61)

61) Операция останова, выполняемая, когда значение целого тип преобразуется в неподписанный тип, не нужно выполнять, когда значение реального плавающего типа преобразуется в неподписанный тип. Таким образом, диапазон (-1, Utype_MAX + 1).

Цитата из N869, 6.3.1.4 Реальные плавающие и целочисленные:

# 1

Когда конечное значение реального плавающего типа преобразуется в целое число типа, отличного от _Bool, дробная часть отбрасывается (т.е. значение усекается к нулю). Если значение интегральной части не может быть представлен целым типом, поведение undefined 0,43)

43) Операция останова, выполняемая, когда значение целого тип преобразуется в неподписанный тип, не нужно выполнять, когда значение реального плавающего типа преобразуется в неподписанный тип. Таким образом, диапазон (-1, Utype_MAX + 1).

Однако, как вы можете видеть из цитат, попытка конвертировать константы с плавающей запятой вне диапазона (-1, Utype_MAX + 1) вызывает поведение undefined.