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

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


person exebook    schedule 22.05.2013    source источник
comment
Здесь я показываю, как выглядят различные NaN, сгенерированные разными способами: #55648118" title="в чем разница между тихой нан и сигнальной нан"> stackoverflow.com/questions/18118408/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 12.04.2019


Ответы (5)


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

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

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

person Mike Seymour    schedule 22.05.2013
comment
Или вы можете сравнить число с самим собой — x == x возвращает false тогда и только тогда, когда x равно NaN. - person Archie; 22.05.2013
comment
@Archie: я не думаю, что это гарантировано на любом языке. - person Mike Seymour; 22.05.2013
comment
@MikeSeymour Не по стандарту языка, но, насколько мне известно, это должно работать, если компилятор утверждает, что он соответствует требованиям IEEE. - person Pixelchemist; 22.05.2013
comment
@Pixelchemist: Действительно, это вариант, если вам нужна запутанность, но не переносимость. Лично я предпочитаю переносимость без обфускации, поэтому сам не буду ее предлагать. - person Mike Seymour; 22.05.2013
comment
второстепенное примечание: NAN - это число с плавающей запятой, а не двойное число. ссылка - person orion elenzil; 19.08.2014
comment
@MikeSeymour (x == x) == false гарантируется в Java, см. grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/ - person Oliv; 06.07.2016
comment
Спасибо за это, я только что решил проблему с внешней библиотекой, которая просто отказывалась правильно компилироваться, потому что не понимала, что означает NAN. - person Len; 02.08.2016
comment
std::numeric_limits<double>::quiet_NaN() не является константой в MSVC++2013. - person Serge Rogatch; 03.09.2016
comment
Возвращает ли std::isnan(a) значение true, если a равно -nan? - person Simon C.; 16.07.2017
comment
Что делать, если вы не можете использовать std::numeric_limits? Есть ли другой способ получить NaN, например константу, определяемую делением нуля на ноль, или это плохая идея? - person Aaron Franke; 07.11.2019
comment
› Или вы можете сравнить число с самим собой — я видел ошибки компилятора, оптимизирующего это. Всегда выполняйте явную проверку. Охота на это - такой кошмар, что она не стоит нулевой выгоды от этого по сравнению с любым надежным методом. - person jheriko; 09.01.2020

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

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

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

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

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

person Shafik Yaghmour    schedule 22.05.2013

Это можно сделать с помощью 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.
person languitar    schedule 22.05.2013
comment
+1. В Википедии есть некоторая информация о тихом NaN и сигнализация NaN. - person Drew Noakes; 13.03.2014

Можно ли назначить 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)
person chux - Reinstate Monica    schedule 19.05.2020
comment
Каковы различия между выводами для разных строк? Какой из них мы должны использовать в типичном числовом коде? - person quant_dev; 26.07.2020
comment
@quant_dev x = NAN; удовлетворяет большинство потребностей, иначе x = nan("0x12345"); — это простой способ указать полезную нагрузку. Различия в содержимом полезной нагрузки определяются реализацией. Обычно MSBit 52-битной полезной нагрузки представляет собой тихий / сигнальный флаг. См. NAN. - person chux - Reinstate Monica; 24.09.2020

да, по концепции указателя вы можете сделать это для переменной int:

int *a;
int b=0;
a=NULL; // or a=&b; for giving the value of b to a
if(a==NULL) 
  printf("NULL");
else
  printf(*a);

это очень просто и прямолинейно. это работало для меня в Arduino IDE.

person Mohammad Reza Abedini    schedule 28.09.2020
comment
NULL и NaN на самом деле не одно и то же - person Benjamin Zach; 28.09.2020
comment
да, они в основном разные, но использование NULL или NaN одинаково в смысле проверки того, является ли переменная числом или нет. - person Mohammad Reza Abedini; 29.09.2020