2016-08-05 6 views
24

Является ли литье бесконечности (представленное float) целым числом неопределенным поведением?Является ли литье бесконечности целым неопределенным?

Стандарт говорит:

4.10 Плавающие-интегральные преобразования

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

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

Я пытаюсь понять, почему std::numeric_limits<int>::infinity() и static_cast<int>(std::numeric_limits<float>::infinity()) имеют разные результаты.

#include <iostream> 
#include <limits> 

int main() 
{ 
    std::cout << std::numeric_limits<int>::infinity() << std::endl; 
    std::cout << static_cast<int> (std::numeric_limits<float>::infinity()) << std::endl; 
    return 0; 
} 

Выход:

0 
-2147483648 

Результат std::numeric_limits<int>::infinity()is well defined и равным 0, но я не могу найти какую-либо информацию о литье бесконечности.

+9

Не забывайте, что 'std :: numeric_limits :: infinity()' полезно только в том случае, если 'std :: numeric_limits :: has_infinity == true', и это не так. – NathanOliver

+0

@NathanOliver, вы правы, но даже если определено 'has_infinity == false' результат' infinity() '. – Gluttton

+0

Я уверен, что значение бесконечности не может быть представлено в 'int'. – aschepler

ответ

15

Вы сказали

Я не могу сказать, является ли «не может быть представлено усеченное значение» охватывает бесконечность

, но все это сводится к

Что такое результат усечения бесконечности.

Стандарт C (входит в C++ с помощью 26,9) отвечает, что совершенно ясно:

C standard semantics for <code>trunc</code>

Поскольку усечение бесконечности все еще бесконечность, а бесконечность не может быть представлена ​​в int (я надеюсь, что там нет вопрос об этой части), поведение не определено.

+3

Есть ли у нас какие-либо доказательства того, что «усечение» в этом смысле эквивалентно поведению функции 'trunc' библиотеки C? –

20

Литье бесконечности в целое число не определено.

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

Говорит все. Поскольку усечение удаляет точность, но не величину, усеченная бесконечность все еще бесконечна, и целые числа не могут представлять бесконечность.

4

Я пытаюсь понять, почему std::numeric_limits<int>::infinity() и static_cast<int>(std::numeric_limits<float>::infinity()) имеют разные результаты.

Стандарт говорит: 18.3.2.4

статическая constexpr Т бесконечности() noexcept;

47 Представление положительной бесконечности, если доступно. [216]

48 Значение для всех специализаций, для которых has_infinity! = False. Требуется в специализациях, для которых is_iec559! = False.

--- редактировать ---

Согласно 18.3.2.7/1 [numeric.special]

1 Все участники должны быть предусмотрены для всех специализаций. Тем не менее, многие значения должны быть значимыми только при определенных условиях (например, epsilon() имеет смысл только в том случае, если is_integer является ложным). Любое значение, которое не является «значимым», должно быть равно 0 или false.

+0

Специализация для 'float' § 18.3.2.7 имеет 'inline static constexpr float infinity() noexcept {возвращаемое значение; } ' – NathanOliver

+0

@BenVoigt Это 18.3.2.7 в моем, соответственно отредактирует. – kfsone