Я столкнулся с проблемой сравнения чисел с плавающей запятой. При сравнении значения с NaN с использованием оператора <
я ожидаю, что будет установлен флаг FE_INVALID
. Оператор <
должен поднимать флаг по стандарту C11 (а также по IEEE-754):
Макрос
isless
определяет, меньше ли его первый аргумент, чем второй аргумент. Значениеisless(x, y)
всегда равно(x) < (y)
; однако, в отличие от(x) < (y)
,isless(x, y)
не вызывает "недопустимое" исключение с плавающей запятой, когдаx
иy
неупорядочены.
Вот пример программы для воспроизведения моей проблемы:
#include <stdio.h>
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
int main()
{
volatile float a = 12.0f;
volatile float b = NAN;
volatile int c;
feclearexcept(FE_ALL_EXCEPT);
c = (a < b);
if (fetestexcept(FE_INVALID))
printf("FE_INVALID\n");
else
printf("Not invalid\n");
return 0;
}
На моей машине (Linux, march=broadwell
) он возвращает «Недействительно». Я скомпилировал его с помощью GCC v7.2.0, используя параметр -std=c11
(отказ от его использования ничего не изменил в результате). Выпущенная инструкция x86 - это UCOMISS
, которая вызывает исключения только для сигнализации NaN - я ожидаю увидеть COMISS
, поскольку это вызовет исключение для всех сравнений NaN, поскольку NaN неупорядочены независимо от того, сигнализируют они или нет.
Я сделал ошибку в своем коде или забыл какой-то параметр компилятора, чтобы поведение соответствовало IEEE? Может ли это быть ошибка (или оптимизация производительности) в компиляторе, чтобы игнорировать необходимость создания исключения здесь?
c
равен 0, хотя я закомментировал pramga, потому что он не распознан. - person Weather Vane   schedule 07.02.2019feclearexcept(FE_ALL_EXCEPT);
возвращает ноль. - person chux - Reinstate Monica   schedule 07.02.2019__STDC_IEC_559__
. Реализация, которая определяет _ STDC_IEC_559 _, должна соответствовать спецификациям в этом приложении. (Соответствует IEEE?) Если__STDC_IEC_559__
не определено, код не указан для того, чтобы вести себя так, как хотелось бы. Единственной ошибкой тогда является неправильное ожидание. - person chux - Reinstate Monica   schedule 07.02.2019feclearexcept
, он возвращает 0. Также очень хороший момент о соответствии IEEE. (Не)к счастью,__STDC_IEC_559__
определено, так что проблема в другом. - person Stefan Mach   schedule 07.02.2019