Как проверить наличие inf (и | или) NaN в двойной переменной - PullRequest
19 голосов
/ 04 ноября 2010

Рассмотрим следующий код:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

template<class T>
bool IsNaN(T t)
{
    return t != t;
}

int main(int argc, char**argv)
{
    double d1, d2;
    sscanf(argv[1], "%f", &d1);
    sscanf(argv[2], "%f", &d2);

    double dRes = d1/d2;

    cout << "dRes = " << dRes << "\n";

    if(IsNaN(dRes))
        cout << "Is NaN\n";
    else
        cout << "Not NaN\n";

}

Пара вопросов:

  1. Когда я передаю 0 и 0 в качестве аргументов, выводится dRes = inf. Но я ожидал dRes = NaN или что-то в этом роде.
  2. Представляется ли NaN двойными переменными? В этом отношении любая переменная?
  3. Когда я изменил тип данных d1, d2, dRes на int и передал 0 и 0, я получил Floating exception. В чем разница?
  4. Как проверить, равно ли значение переменной inf?

Ответы [ 3 ]

28 голосов
/ 04 ноября 2010
  1. При использовании scanf() double следует читать с использованием %lf, а не %f. %f преобразует ввод в 32-битный float, поэтому первые 32 бита ваших переменных будут заполнены некоторыми недопустимыми данными, а последние 32 бита будут оставлены как мусор.

  2. Да. #include <limits>, , затем std::numeric_limits<double>::quiet_NaN(). Некоторые компиляторы (например, gcc) также предоставляют макрос NAN в <cmath>.

  3. Для целочисленных типов нет NaN или бесконечности. Деление на ноль для целого числа вызовет исключение (SIGFPE) .

  4. #include <cmath>, затем std::isinf(x). Используйте std::isfinite(x), чтобы x не было NaN или Infinity.

0 голосов
/ 14 января 2018

Функция fpclassify позволит вам проверить значение с плавающей запятой для всех особых случаев.

Он найден в <math.h> как макрос с C99 и в <cmath> как семейство функций, для float, double и long double под перегруженным именем std::fpclassify с C ++ 11.

cppreference имеет хороший пример

0 голосов
/ 14 января 2018

Просто сделай так:

if (dRes  == +1.0/0.0 || dRes  == -1.0/0.0) ... //+INF, -INF
if (dRes  == +0.0/0.0 ) ... //+NaN; i.e. pow(2.0 ,16384.0)
...