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

234
04 августа 2017, 01:17

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

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

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

  • Clang
  • GCC
  • MSVC

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

Answer 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.

Ответ навеян замечательный постом от Реймонда Чена.

READ ALSO
Таймаут Write Read

Таймаут Write Read

getlasteror дает ошибку 1008 ругается на hUsb помогите

295
Получение подключенных устройств к Linux на C

Получение подключенных устройств к Linux на C

Задача следующая: необходимо на C/C++ получить список подключенных к ПК на Linux подключенных USB-устройств

277
Продвинутое изучение С++ [дубликат]

Продвинутое изучение С++ [дубликат]

На данный вопрос уже ответили:

272