Константа C / с ++ NaN (буквальная)?

110

Возможно ли это , чтобы назначить NaNк doubleили floatв C / C ++? Как и в JavaScript вы: a = NaN. Так что позже вы можете проверить, является ли переменная числом или нет.

exebook
источник
Здесь я показываю, как выглядят различные NaN, генерируемые разными способами: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Ответы:

153

В C NANобъявлен в <math.h>.

В C ++ std::numeric_limits<double>::quiet_NaN()объявлен в <limits>.

Но для проверки того, является ли значение NaN, вы не можете сравнить его с другим значением NaN. Вместо этого используйте isnan()from <math.h>в C или std::isnan()from <cmath>в C ++.

Майк Сеймур
источник
20
Или вы можете сравнить это число с самим собой - x == xвозвращает, falseесли и только если xэто NaN.
Арчи
7
@Archie: Я не думаю, что это гарантировано ни на одном из языков.
Майк Сеймур
3
@MikeSeymour Не по стандарту языка, но, насколько я знаю, он должен работать, если компилятор утверждает, что он соответствует требованиям IEEE.
Pixelchemist
39
@Pixelchemist: Действительно, это вариант, если вам нужна обфускация, но не переносимость. Лично я предпочитаю переносимость без обфускации, поэтому сам предлагать ее не буду.
Майк Сеймур
9
второстепенное примечание: NAN - это число с плавающей запятой, а не двойное. ссылка
orion elenzil
23

Как отмечали другие, вы ищете, std::numeric_limits<double>::quiet_NaN()хотя я должен сказать, что предпочитаю документы cppreference.com . Тем более, что это утверждение немного расплывчато:

Имеет смысл, только если std :: numeric_limits :: has_quiet_NaN == true.

и было несложно понять, что это означает на этом сайте, если вы посмотрите их раздел на std::numeric_limits::has_quiet_NaNнем:

Эта константа имеет смысл для всех типов с плавающей запятой и гарантированно верна, если std :: numeric_limits :: is_iec559 == true.

что, как объясняется здесь , trueозначает, что ваша платформа поддерживает IEEE 754стандарт. Этот предыдущий поток объясняет, что это должно быть верно для большинства ситуаций.

Шафик Ягмур
источник
9

Это можно сделать с помощью numeric_limits в C ++:

http://www.cplusplus.com/reference/limits/numeric_limits/

Вот методы, на которые вы, вероятно, захотите обратить внимание:

infinity()  T   Representation of positive infinity, if available.
quiet_NaN() T   Representation of quiet (non-signaling) "Not-a-Number", if available.
signaling_NaN() T   Representation of signaling "Not-a-Number", if available.
лангитар
источник
6
+1. В Википедии есть информация о тихом NaN и сигнальном NaN .
Дрю Ноукс
1

Возможно ли присвоить NaN двойному или плавающему в C ...?

Да, поскольку C99 (C ++ 11) <math.h>предлагает следующие функции:

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

которые похожи на своих strtod("NAN(n-char-sequence)",0)собратьев и NANдля заданий.

// Sample C code
uint64_t u64;
double x;
x = nan("0x12345");
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = -strtod("NAN(6789A)",0);
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = NAN;
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);

Пример вывода: (зависит от реализации)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - восстановить Монику
источник
1
В чем разница между выводами для разных строк? Какой из них мы должны использовать в типичном числовом коде?
Quant_dev