Предположим, у меня есть два арифметических типа, целочисленный один, I
и с плавающей точкой один, F
. Я также предполагаю, что std::numeric_limits<I>::max()
меньше, чем std::numeric_limits<F>::max()
.Является ли округление с плавающей точкой всегда определяемым поведением, если диапазон с плавающей запятой больше?
Теперь, скажем, у меня есть положительное целочисленное значение i
. Поскольку представляемый диапазон F
больше I
, F(i)
всегда должен определяться поведением.
Однако, если у меня есть значение с плавающей запятой f
такое, что f == F(i)
, is I(f)
четко определено? Другими словами, всегда задано поведение I(F(i))
?
соответствующий раздел из стандарта C++ 14:
4.9 Плавающие-интегральные преобразования[conv.fpint]
- prvalue типа с плавающей точкой может быть преобразовано в prvalue целочисленного типа. Преобразование усекает; , то есть дробная часть отбрасывается. Поведение не определено, если усеченное значение не может быть , представленное в типе назначения. [Примечание: Если тип адресата
bool
, см. 4.12. - конец примечания]- Предел целочисленного типа или типа перечислимого типа не может быть преобразован в значение значения плавающего типа . Результат является точным, если это возможно. Если преобразованное значение находится в диапазоне значений, которые могут быть представлены , но значение не может быть представлено точно, это выбор, определенный реализацией либо следующим нижним, либо более высоким представляемым значением. [Примечание: Потеря точности происходит, если интегральное значение не может быть представлено точно как значение плавающего типа. - конец примечания] Если преобразованное значение находится вне диапазон значений, которые могут быть представлены, поведение не определено. Если тип источника
bool
, значениеfalse
преобразуется в ноль, а значениеtrue
преобразуется в единицу.
@vsoftco Вам придется перефразировать это. 'I <= i' не имеет смысла - вы сравниваете тип со значением. – orlp
[Нет] (http://coliru.stacked-crooked.com/a/e58cd5864d532045). –
Представьте, что 'I' и' F' имеют одинаковый размер, скажем 32 бита. Затем возьмем наибольшее целое число. Он обязательно преобразует с потерей значения в значение типа 'F'. Если выбранное значение, которое выбрано, больше, чем следующее целое число, то преобразование результатов обратно в UB. –