Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 65, средняя оценка - 4.88
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
#1

Как вернуть NaN и Infinity, проверить на NaN и Infinity? - C++

30.03.2011, 08:08. Просмотров 9939. Ответов 40
Метки нет (Все метки)

Как вернуть NaN и Infinity, проверить на NaN и Infinity?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.03.2011, 08:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как вернуть NaN и Infinity, проверить на NaN и Infinity? (C++):

Проверка double на NaN и Infinity - C++
Как лучше проверить дабл на нотенамбер или бесконечность?

infinity размер - C++
Вопрос почему при заданной размерности я могу добавлять бесконечно? Оо class stack{ private: int count; int *st; public: ...

Как отловить +/-INF и NAN? - C++
Здравствуйте. Проблема в возникновении в ходе вычислений указанных в заголовке значений. Причем трагизм ситуации в том, что после начала...

Как присвоить переменной Double значение NaN? - C++
Есть переменная типа double. Как ей присвоить значение NaN?

nan - C++
подскажите что это означает ввожу данные на выходе "nan" работаю только с double, long int

Проверка на NaN (С/С++) - C++
Подскажите, пожалуйста, как проверить является ли вещественное число NaN'ом? Как вариант сделать побитовое умножение на маску... Но...

40
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 07:27  [ТС] #16
А как проверить на inf? MSDN предлагает функцию _finite, но она специфична для их среды, кодоблоки её не понимают.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6521 / 3160 / 311
Регистрация: 04.12.2011
Сообщений: 8,762
Записей в блоге: 5
18.07.2015, 07:47 #17
taras atavin, вот давненько смотрел, правда, но проверял вроде:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//http://www.johndcook.com/IEEE_exceptions_in_cpp.html
 
bool IsNumber(double x) 
    {
        // This looks like it should always be true, 
        // but it's false if x is a NaN.
        return (x == x); 
    }
 
//Here DBL_MAX is a constant defined in float.h as the largest double that can be represented.
 
bool IsFiniteNumber(double x) 
    {
        return (x <= DBL_MAX && x >= -DBL_MAX); 
    }   
 
непрохождение первого теста говорит о том что x не число (например результат ln(-1))
непрохождение второго - о том, что x бесконечность (+ или -) в зависимости от знаков операндов в операции в которой получен результат. 
 
To get more detail about the type of a floating point number, there is a function _fpclass on Windows and a corresponding function fp_class_d on Linux. I have not been able to get the corresponding Linux code to work and so I'll stick to what I've tested and just talk about Windows from here on out.
The Windows function _fpclass returns one of the following values:
 
    _FPCLASS_SNAN   // signaling NaN
        _FPCLASS_QNAN   // quiet NaN
        _FPCLASS_NINF   // negative infinity
        _FPCLASS_NN     // negative normal
        _FPCLASS_ND     // negative denormal
        _FPCLASS_NZ     // -0
        _FPCLASS_PZ     // +0
        _FPCLASS_PD     // positive denormal
        _FPCLASS_PN     // positive normal
        _FPCLASS_PINF   // positive infinity  
 
The following code illustrates which kinds of operations result in which kinds of numbers. To port this code to Linux, the FPClass function would need to use fp_class_d and its corresponding constants. 
 
 
    #include <cfloat>
        #include <iostream>
        #include <sstream>
        #include <cmath>
 
        using namespace std;
 
        string FPClass(double x)
        {
            int i = _fpclass(x);
            string s;
            switch (i)
            {
            case _FPCLASS_SNAN: s = "Signaling NaN";                break;
            case _FPCLASS_QNAN: s = "Quiet NaN";                    break; 
            case _FPCLASS_NINF: s = "Negative infinity (-INF)";     break; 
            case _FPCLASS_NN:   s = "Negative normalized non-zero"; break;
            case _FPCLASS_ND:   s = "Negative denormalized";        break; 
            case _FPCLASS_NZ:   s = "Negative zero (-0)";           break; 
            case _FPCLASS_PZ:   s = "Positive 0 (+0)";              break; 
            case _FPCLASS_PD:   s = "Positive denormalized";        break; 
            case _FPCLASS_PN:   s = "Positive normalized non-zero"; break; 
            case _FPCLASS_PINF: s = "Positive infinity (+INF)";     break;
            }
            return s;
        }
 
        string HexDump(double x)
        {
            unsigned long* pu;
            pu = (unsigned long*)&x;
            ostringstream os;
            os << hex << pu[0] << " " << pu[1];
            return os.str();
        }
 
        // ----------------------------------------------------------------------------
        int main()
        {
            double x, y, z;
 
            cout << "Testing z = 1/0\n";
            // cannot set x = 1/0 directly or would produce compile error.
            x = 1.0; y = 0; z = x/y;
            cout << "z = " << x/y << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = -1/0\n";
            x = -1.0; y = 0; z = x/y;
            cout << "z = " << x/y << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = sqrt(-1)\n";
            x = -1.0;
            z = sqrt(x);
            cout << "z = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = log(-1)\n";
            x = -1.0;
            z = sqrt(x);
            cout << "z = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting overflow\n";
            z = DBL_MAX;
            cout << "z = DBL_MAX = " << z; 
            z *= 2.0;
            cout << "; 2z = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting denormalized underflow\n";
            z = DBL_MIN;
            cout << "z = DBL_MIN = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
            z /= pow(2.0, 52);
            cout << "z = DBL_MIN / 2^52= " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
            z /= 2;
            cout << "z = DBL_MIN / 2^53= " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = +infinity + -infinty\n";
            x = 1.0; y = 0.0; x /= y; y = -x;
            cout << x << " + " << y << " = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = 0 * infinity\n";
            x = 1.0; y = 0.0; x /= y; z = 0.0*x;
            cout << "x = " << x << "; z = 0*x = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting 0/0\n";
            x = 0.0; y = 0.0; z = x/y;
            cout << "z = 0/0 = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting z = infinity/infinity\n";
            x = 1.0; y = 0.0; x /= y; y = x; z = x/y;
            cout << "x = " << x << "; z = x/x = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting x fmod 0\n";
            x = 1.0; y = 0.0; z = fmod(x, y);
            cout << "fmod(" << x << ", " << y << ") = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nTesting infinity fmod x\n";
            y = 1.0; x = 0.0; y /= x; z = fmod(y, x);
            cout << "fmod(" << y << ", " << x << ") = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            cout << "\nGetting cout to print QNAN\n";
            unsigned long nan[2]={0xffffffff, 0x7fffffff};
            z = *( double* )nan;
            cout << "z = " << z << "\n";
            cout << HexDump(z) << " _fpclass(z) = " << FPClass(z) << "\n";
 
            return 0;
        }      
 
 
немного о представлении:
// numeric_limits_infinity.cpp
// compile with: /EHsc
#include <iostream>
#include <limits>
 
using namespace std;
 
int main( )
{
   cout << numeric_limits<float>::has_infinity <<endl;
   cout << numeric_limits<double>::has_infinity<<endl;
   cout << numeric_limits<long double>::has_infinity <<endl;
   cout << numeric_limits<int>::has_infinity <<endl;
   cout << numeric_limits<__int64>::has_infinity <<endl;
 
   cout << "The representation of infinity for type float is: "
        << numeric_limits<float>::infinity( ) <<endl;
   cout << "The representation of infinity for type double is: "
        << numeric_limits<double>::infinity( ) <<endl;
   cout << "The representation of infinity for type long double is: "
        << numeric_limits<long double>::infinity( ) <<endl;
}
 
и 
Константа NaN смысла не имеет: все равно сравнивать значения с ней нельзя.
 
Константы +-Infinity в C++ получить легко:
 
std::numeric_limits<double>::infinity();
-std::numeric_limits<double>::infinity();
.
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 08:46  [ТС] #18
Цитата Сообщение от IGPIGP Посмотреть сообщение
Константы +-Infinity в C++ получить легко: std::numeric_limits<double>::infinity(); -std::numeric_limits<double>::infinity();
С ними можно сравнивать?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6521 / 3160 / 311
Регистрация: 04.12.2011
Сообщений: 8,762
Записей в блоге: 5
18.07.2015, 10:18 #19
Цитата Сообщение от taras atavin Посмотреть сообщение
С ними можно сравнивать?
В первых двух примерах (втором точнее) показано как проверить ограниченно ли значение. Если не ограничено то бесконечность. Более того там два сравнения конкатенируются && то есть легко использовать любое из них для определения знака бесконечности. Сам факт сравнения с DBL_MAX говорит о том, что оно работает и когда сравниваемое значение равно (Вы не поверите) std::numeric_limits<double>::infinity()
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 11:06  [ТС] #20
А с
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
std::numeric_limits<double>::infinity()
и
C++
1
-std::numeric_limits<double>::infinity();
можно сравнивать?
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,307
Завершенные тесты: 1
18.07.2015, 12:01 #21
taras atavin,
http://en.cppreference.com/w/cpp/numeric/math/fpclassify
В секции See Also тоже посмотри.
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 12:09  [ТС] #22
const char* show_classification(double x)
И что я потом с этим указателем на char буду делать? Ещё функцию, возвращающую сэмпл с голосовым сообщением предложите.

Добавлено через 1 минуту
Цитата Сообщение от ct0r Посмотреть сообщение
В секции See Also тоже посмотри.
C:\Projects\Test10\Test10\Test.cpp|7|error: 'isfinite' is not a member of 'std'|
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,307
Завершенные тесты: 1
18.07.2015, 12:13 #23
Цитата Сообщение от taras atavin Посмотреть сообщение
И что я потом с этим указателем на char буду делать? Ещё функцию, возвращающую сэмпл с голосовым сообщением предложите.
Алё, функция это fpclassify, а show_classification это иллюстративный пример ее применения. Уж простите, но если такое не доходит, пора на пенсию и внуков няньчить.

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
C:\Projects\Test10\Test10\Test.cpp|7|error: 'isfinite' is not a member of 'std'|
Должен быть включен хедер cmath и поддержка С++11.
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 12:16  [ТС] #24
Цитата Сообщение от ct0r Посмотреть сообщение
Уж простите, но если такое не доходит, пора на пенсию и внуков няньчить.
Может если доходит? Потому что ничего он не иллюстрирует.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6521 / 3160 / 311
Регистрация: 04.12.2011
Сообщений: 8,762
Записей в блоге: 5
18.07.2015, 15:06 #25
Цитата Сообщение от taras atavin Посмотреть сообщение
можно сравнивать?
Сравнивать что? Их же, - нельзя. То есть вообще можно всё, но результат будет нелогичный. Вещь сама себе неравна может быть? Легко.
taras atavin, ведь в примере показано как пошагово определить NAN, далее бесконечность и её знак. Чего же ещё желать? У Вас задача определить или понять, что можно сравнивать?
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 15:08  [ТС] #26
Цитата Сообщение от IGPIGP Посмотреть сообщение
taras atavin, ведь в примере показано как пошагово определить NAN, далее бесконечность и её знак. Чего же ещё желать?
Лишняя сущность.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6521 / 3160 / 311
Регистрация: 04.12.2011
Сообщений: 8,762
Записей в блоге: 5
18.07.2015, 15:12 #27
Цитата Сообщение от taras atavin Посмотреть сообщение
Лишняя сущность.
Боюсь догадаться о чём это Вы сейчас. Ниже перечислены темы про изнанку С++. Там изнан на изнане на все вкусы. Присмотрите что-нибудь не лишнее.
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 15:13  [ТС] #28
О дабломаксе конечно.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6521 / 3160 / 311
Регистрация: 04.12.2011
Сообщений: 8,762
Записей в блоге: 5
18.07.2015, 15:17 #29
Цитата Сообщение от taras atavin Посмотреть сообщение
О дабломаксе конечно.
Это Вы сгоряча.
0
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.07.2015, 15:20  [ТС] #30
Разве? Мне ваще то не нужен максимум дабла. К тому же я ведь могу и поменять тип на float, или на long double. Вот представьте себе: есть некая интовая переменная, надо проверить, равна ли она единице. Вы как проверять будете?
C++
1
if ((x>0)&&(x<2))
?
0
18.07.2015, 15:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.07.2015, 15:20
Привет! Вот еще темы с ответами:

Что такое nan? - C++
Собственно вопрос: что такое nan? Допустим v=2 #include&lt;iostream&gt; #include&lt;cmath&gt; using namespace std; int main() { ...

max [NaN, число] vs max [число, NaN] - C++
объясните пожалуйста, в чем прикол? double a = numeric_limits&lt;double&gt;::quiet_NaN(); double b = 1.0; double c = max(b, a); // с =...

Nan после вычисления - C++
после вычисления значения выдает число, nan, число. как можно округлить до того значения, чтобы выдавался корректный ответ? + после...

LU - разложение (выдает NaN) - C++
Здравствуйте. Помогите исправить программу. Проблема заключается в том, что некоторые значение получаются NaN/ #include&lt;iostream.h&gt; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.