Я хотел бы попытаться выставить NaN путем логического рассмотрения.
Если float
равно , не бесконечно (ни больше, чем FLT_MAX
, ни меньше чем -FLT_MAX
), поэтому оно должно быть меньше или равно FLT_MAX
. Если нет, то это NaN .
int is_inf(float x) { return x < -FLT_MAX || x > FLT_MAX; }
int is_nan(float x) { return !is_inf(x) && !(x <= FLT_MAX); }
Мой самый первый ответ, и он уже проголосовал. Поэтому я решил добавить пример. Ну, это работает, как и ожидалось.
#include <stdio.h>
#include <math.h>
#include <float.h>
static int is_inf(float x) { return x < -FLT_MAX || x > FLT_MAX; }
static int is_nan(float x) { return !is_inf(x) && !(x <= FLT_MAX); }
static void show(float f)
{
float g = -f;
printf("% f : %i %i %i %i\n", f, isinf(f), isnan(f), is_inf(f), is_nan(f));
printf("% f : %i %i %i %i\n", g, isinf(g), isnan(g), is_inf(g), is_nan(g));
}
int main(void)
{
float inf = FLT_MAX * 2.0f;
float nan = inf / inf;
show(inf);
show(nan);
show(FLT_MAX);
show(FLT_MIN);
show(0.0f);
show(1234.5678f);
return 0;
}
Скомпилировано и запущено в Linux:
$ gcc infnan.c
$ ./a.out
inf : 1 0 1 0
-inf : -1 0 1 0
-nan : 0 1 0 1
nan : 0 1 0 1
340282346638528859811704183484516925440.000000 : 0 0 0 0
-340282346638528859811704183484516925440.000000 : 0 0 0 0
0.000000 : 0 0 0 0
-0.000000 : 0 0 0 0
0.000000 : 0 0 0 0
-0.000000 : 0 0 0 0
1234.567749 : 0 0 0 0
-1234.567749 : 0 0 0 0
Дополнительное решение для типа данных double
с улучшенным возвращаемым значением.
static int is_inf(double x) {
if (x > DBL_MAX) return 1;
if (x < -DBL_MAX) return -1;
return 0;
}
static int is_nan(double x) { return !is_inf(x) && !(x <= DBL_MAX); }
Подумав еще раз, is_nan
можно вычислить проще.
int is_nan(double x) { return !(x > DBL_MAX || x <= DBL_MAX); }
Или даже без включенной константы.
int is_nan(double x) { return !(x > 0.0 || x <= 0.0); }