Подтвердить что ты не робот

Почему GCC дает -nan и clang и Intel yield + nan для 0.0/0.0?

Когда я отлаживал код, я обнаружил, что GCC и Clang дают уроки nan для 0.0/0.0, чего я ожидал, но GCC дает нано с битом знака, установленным в 1, а Clang устанавливает его в 0 (в согласие с ICC, если я правильно помню).

Теперь очевидно, что обе формы разрешены, но я продолжаю задаваться вопросом, почему 0.0/0.0 сделает вывод GCC "отрицательным" результатом (печать дает -nan), а -(0.0/0.0) дает "положительный" результат? Еще более запутанным является то, что -0.0/0.0 снова "отрицательный". Это постоянная складчатая странность?

изменить

Собственно, это постоянное сгибание, которое делает его положительным наном. Если я вынужу вычисление во время выполнения, я получаю отрицательный нан как на GCC, так и на Clang

volatile float zero = 0.0;
std::cout << (zero/zero); // -nan

Может кто-нибудь рассказать об этом, пожалуйста? Является ли бит знака установлен равным 1 на FPU x86?

4b9b3361

Ответ 1

IEEE-754 не указывает знак NaN:

Когда либо вход, либо результат NaN, этот стандарт не интерпретировать знак NaN. Обратите внимание, однако, что операции с битом строки - copy, negate, abs, copySign - указать бит знака результата NaN, иногда на основе знакового бита операнда NaN. логический предикат totalOrder также зависит от знакового бита NaN-операнд. Для всех других операций этот стандарт не указывает знаковый бит результата NaN, даже если имеется только один вход NaN, или когда NaN создается из недействительной операции.

Теперь рассмотрим Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture.

В этом случае Intel в этом случае указывает конкретное значение NaN, которое называется QNaN Floating-Point Indefinite (см. таблицу 4-1), которое возвращается при #IA (неверное арифметическое исключение) (см. таблицу 8-10). Найдите деление 0 на 0.

Вы видите, что для этого значения установлен знаковый бит.