Почему errno не установлен в EDOM, даже если sqrt вынимает спор о домене? - PullRequest
2 голосов
/ 21 мая 2019

errno не устанавливается в EDOM для ошибки домена функции sqrt () в windows В Linux он отображается правильно, но не работает в Windows (с использованием GCC 7.4) ...

#include <stdio.h>
#include <errno.h>
#include <math.h>

int main () {
double val;

errno = 0;
val = sqrt(-10);

if(errno == EDOM) {
printf("Invalid value \n");
} else {
printf("Valid value\n");
} 

errno = 0;
val = sqrt(10);

if(errno == EDOM) {
printf("Invalid value\n");
} else {
printf("Valid value\n");
}

return(0);
}

Ожидаемый результат: Неверное значение Допустимое значение Фактический результат: действительное значение Допустимое значение

Ответы [ 2 ]

3 голосов
/ 21 мая 2019

Математические функции не требуются для установки errno. Они могут , но они не обязаны. См. раздел 7.12.1 стандарта C . Теоретически вы можете проверить значение глобальной константы math_errhandling, чтобы выяснить, будут ли они, но это не совсем надежно для любой реализации, о которой я знаю, и может даже не быть определено (это макрос, так что вы можете по крайней мере использовать #ifdef проверить это).

Вместо этого вы можете проверить, является ли вход отрицательным перед вызовом sqrt, или (если ваша реализация должным образом поддерживает IEEE 754), вы можете проверить, является ли вывод NaN (используя isnan) впоследствии.

0 голосов
/ 21 мая 2019

Как заметил @zwol, Стандарт позволяет реализациям некоторую широту относительно того, как (и ли) математические функции сигнализируют об ошибках. В частности:

При ошибке в домене функция возвращает определенный реализацией значение; если целочисленное выражение math_errhandling & MATH_ERRNO ненулевое целочисленное выражение errno получает значение EDOM; если целочисленное выражение math_errhandling & MATH_ERREXCEPT отлично от нуля, '' Неверное '' исключение с плавающей запятой.

( C11, пункт 7.12.1 / 2 )

При доменной ошибке в sqrt,

  • В Linux с glibc , NaN возвращается, errno устанавливается на EDOM, и возникает исключение с плавающей точкой.

  • В Windows с недавней библиотекой времени выполнения MS возвращается неопределенный NaN и возникает исключение с плавающей запятой, может быть ( документы мне немного неясны, но определенно что-то вроде установлен флаг статуса, который можно впоследствии оценить с помощью функции _matherr()). Там нет упоминания о настройке errno.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...