Как использовать nan и inf в C?

У меня есть численный метод, который мог возвратить nan или inf, если бы была ошибка, и для тестирования, ставившего целью, я хотел бы временно вынудить это возвратить nan или inf, чтобы гарантировать, что ситуация обрабатывается правильно. Существует ли надежный, независимый от компилятора способ создать стоимость nan и inf в C?

После поиска с помощью Google в течение приблизительно 10 минут я только смог найти зависимые решения для компилятора.

84
задан Cœur 30 July 2017 в 10:26
поделиться

5 ответов

Вы можете проверить, есть ли он в вашей реализации:

#include <math.h>
#ifdef NAN
/* NAN is supported */
#endif
#ifdef INFINITY
/* INFINITY is supported */
#endif

Существование INFINITY ] гарантируется C99 (или, по крайней мере, последним черновиком), и "расширяется до константного выражения типа float, представляющего положительный или беззнаковый бесконечность, если есть; else на положительную константу типа float, которая переполняется во время трансляции. "

NAN может быть определен или не определен, и" определяется тогда и только тогда, когда реализация поддерживает тихие NaN для типа float. Он расширяется до константного выражения типа float, представляющего тихое NaN. "

Обратите внимание, что если вы сравниваете значения с плавающей запятой и делаете:

a = NAN;

даже тогда,

a == NAN;

ложно. Один из способов проверить NaN будет:

#include <math.h>
if (isnan(a)) { ... }

Вы также можете выполнить: a! = a , чтобы проверить, является ли a NaN.

Также существует isfinite () , isinf () , isnormal () и signbit () макросы в math.h в C99.

C99 также имеет nan функции:

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

(Ссылка: n1256).

Docs INFINITY Docs NAN

79
ответ дан 24 November 2019 в 08:33
поделиться

Независимый от компилятора, но не независимый от процессора способ получить их:

int inf = 0x7F800000;
return *(float*)&inf;

int nan = 0x7F800001;
return *(float*)&nan;

Это должно работать на любом процессоре, который использует формат с плавающей запятой IEEE 754 (что и есть в x86).

ОБНОВЛЕНИЕ: проверено и обновлено.

20
ответ дан 24 November 2019 в 08:33
поделиться

Не существует независимого от компилятора способа сделать это, поскольку ни стандарты C (ни C ++) не говорят, что математические типы с плавающей запятой должны поддерживать NAN или INF.

Изменить: Я только что проверил формулировку стандарта C ++, и там говорится, что эти функции (члены шаблонного класса numeric_limits):

quiet_NaN() 
signalling_NaN()

будут возвращать представления NAN «если они доступны». Он не расширяет то, что означает «если доступно», но, по-видимому, что-то вроде «если представитель реализации FP поддерживает их». Точно так же есть функция:

infinity() 

, которая возвращает положительный INF rep «если доступно».

Оба они определены в заголовке - я полагаю, что в стандарте C есть что-то аналогично (вероятно, также "если есть"), но я не

34
ответ дан 24 November 2019 в 08:33
поделиться

Это работает как для float и двойной :

double NAN = 0.0/0.0;
double POS_INF = 1.0 /0.0;
double NEG_INF = -1.0/0.0;

Редактировать: Как кто-то уже сказал, старый стандарт IEEE сказал, что такие ценности должны создавать ловушки. Но новые компиляторы почти всегда выключают ловушки и возвращают данные значения, потому что захват мешает ошибке обработка.

20
ответ дан 24 November 2019 в 08:33
поделиться

Я также удивлен, что это не константы времени компиляции. Но я полагаю, вы могли бы достаточно легко создать эти значения, просто выполнив инструкцию, которая возвращает такой недопустимый результат. Деление на 0, логарифм 0, загар 90 и тому подобное.

0
ответ дан 24 November 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: