Является ли static_cast <double>(std :: nanf ("")) хорошо определенным? - PullRequest
0 голосов
/ 31 октября 2018

Название в значительной степени спрашивает все это, но предоставить MCVE:

#include <cmath>

int main()
{
    float f = std::nanf("");
    double d = static_cast<double>(f);
    return 0;
}

В MSVC 2017 и f, и d сообщают как nan, но это ничего не доказывает, поскольку возможно, что static_cast - неопределенное поведение.

Аналогичным образом, 0.0f / 0.0f производит -nan(ind), который, как я собираюсь предположить, является сигнальным наном, соответствует ли это тому же определенному / неопределенному правилу? То же самое inf.

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Это выглядит гарантированно стандартом, мы можем начать с раздела [expr.static.cast] p4 , который говорит:

Выражение e может быть явно преобразовано в тип T, если существует неявная последовательность преобразования из e в T ...

последовательность неявного преобразования описана в [over.best.ics] , и мы имеем следующее:

Правильно сформированная неявная последовательность преобразования является одной из следующих форм:
- (3.1) стандартная последовательность преобразования,
...

и стандартная последовательность преобразования указана в [over.ics.scs] , которая гласит:

[Примечание: как описано в [conv], стандартной последовательностью преобразования является либо преобразование идентичности само по себе (то есть без преобразования), либо оно состоит из одного-трех преобразований из других четырех категорий. Если в последовательности есть два или более преобразований, преобразования применяются в каноническом порядке: преобразование Lvalue, повышение или преобразование, корректировка квалификации. - конец примечания]

и у нас есть случай продвижения с плавающей запятой, который мы здесь рассмотрели в [conv.fpprom] p1 , который гласит:

Значение типа float может быть преобразовано в значение типа double. Значение не изменяется.

Переход в другую сторону double в float будет преобразованием, которое рассматривается в [conv # double] p1 :

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

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

Вопрос о делении с плавающей точкой на ноль сложен и описан в моем ответе на Поведение деления с плавающей точкой на ноль .

0 голосов
/ 31 октября 2018

static_cast просто продвигает float, что всегда определяется. Деление на ноль равно undefined (даже без приведения), хотя многие реализации допускают его для типов с плавающей запятой в соответствии с правилами IEEE 754. Сигнальные NaN никогда не встречаются в обычных системах; вместо них используются исключения с плавающей точкой .

...