Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Смысловая нагрузка значения “минус NaN”

#cpp #nan


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

#include 

int main()
{
    double zero = 0;
    std::cout << 0/zero << "\n";
}


Результат получается одинаковым для основных наиболее популярных компиляторов:


Clang
GCC
MSVC


Есть ли какой-то практический смысл в этом минусе, почему не просто nan?
    


Ответы

Ответ 1



Получается это из-за того, что все вышеозначенные примеры были запущены на x86 архитектуре, а для FPU оной есть такое правило: When neither of the source operands is a NaN, but the operation generates a floating-point invalid-operation exception (see Tables 8-10 and 11-1), the result is commonly a QNaN FP Indefinite (Section 4.8.3.7). Взятое из Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture параграфа 4.8.3.5. Заглянув в таблицу, указанную в цитате выше, мы обнаружим там следующую операцию, которая даёт на выходе QNaN: Division: ∞ by ∞ ; 0 by 0. Т.е. как раз то, что у нас и есть в вопросе (там есть и другие операции). А если мы посмотрим на таблицу 4-3, из секции 4.2.2, то увидим, что у QNaN знаковый бит выставлен в 1, что объясняет появление отрицательного NaN в выводе. А если посмотреть на это всё с точки зрения языка, то получается неопределённое поведение, поэтому видеть мы можем всё, что угодно. C++14, [expr]p4: If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. Ответ навеян замечательный постом от Реймонда Чена.

Комментариев нет:

Отправить комментарий