Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 65, средняя оценка - 4.88
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

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

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

Как вернуть NaN и Infinity, проверить на NaN и Infinity?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.03.2011, 08:08     Как вернуть NaN и Infinity, проверить на NaN и Infinity?
Посмотрите здесь:
C++ Проверка double на NaN и Infinity
C++ infinity размер
Как отловить +/-INF и NAN? C++
Как присвоить переменной Double значение NaN? C++
nan C++
C++ Проверка на NaN (С/С++)
LU - разложение (выдает NaN) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 07:27  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #16
А как проверить на inf? MSDN предлагает функцию _finite, но она специфична для их среды, кодоблоки её не понимают.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6444 / 3083 / 306
Регистрация: 04.12.2011
Сообщений: 8,496
Записей в блоге: 4
18.07.2015, 07:47     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #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();
.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 08:46  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #18
Цитата Сообщение от IGPIGP Посмотреть сообщение
Константы +-Infinity в C++ получить легко: std::numeric_limits<double>::infinity(); -std::numeric_limits<double>::infinity();
С ними можно сравнивать?
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6444 / 3083 / 306
Регистрация: 04.12.2011
Сообщений: 8,496
Записей в блоге: 4
18.07.2015, 10:18     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #19
Цитата Сообщение от taras atavin Посмотреть сообщение
С ними можно сравнивать?
В первых двух примерах (втором точнее) показано как проверить ограниченно ли значение. Если не ограничено то бесконечность. Более того там два сравнения конкатенируются && то есть легко использовать любое из них для определения знака бесконечности. Сам факт сравнения с DBL_MAX говорит о том, что оно работает и когда сравниваемое значение равно (Вы не поверите) std::numeric_limits<double>::infinity()
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 11:06  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #20
А с
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
std::numeric_limits<double>::infinity()
и
C++
1
-std::numeric_limits<double>::infinity();
можно сравнивать?
ct0r
Игогошка!
1768 / 670 / 42
Регистрация: 19.08.2012
Сообщений: 1,284
Завершенные тесты: 1
18.07.2015, 12:01     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #21
taras atavin,
http://en.cppreference.com/w/cpp/num...ath/fpclassify
В секции See Also тоже посмотри.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 12:09  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #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'|
ct0r
Игогошка!
1768 / 670 / 42
Регистрация: 19.08.2012
Сообщений: 1,284
Завершенные тесты: 1
18.07.2015, 12:13     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #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.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 12:16  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #24
Цитата Сообщение от ct0r Посмотреть сообщение
Уж простите, но если такое не доходит, пора на пенсию и внуков няньчить.
Может если доходит? Потому что ничего он не иллюстрирует.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6444 / 3083 / 306
Регистрация: 04.12.2011
Сообщений: 8,496
Записей в блоге: 4
18.07.2015, 15:06     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #25
Цитата Сообщение от taras atavin Посмотреть сообщение
можно сравнивать?
Сравнивать что? Их же, - нельзя. То есть вообще можно всё, но результат будет нелогичный. Вещь сама себе неравна может быть? Легко.
taras atavin, ведь в примере показано как пошагово определить NAN, далее бесконечность и её знак. Чего же ещё желать? У Вас задача определить или понять, что можно сравнивать?
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 15:08  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #26
Цитата Сообщение от IGPIGP Посмотреть сообщение
taras atavin, ведь в примере показано как пошагово определить NAN, далее бесконечность и её знак. Чего же ещё желать?
Лишняя сущность.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6444 / 3083 / 306
Регистрация: 04.12.2011
Сообщений: 8,496
Записей в блоге: 4
18.07.2015, 15:12     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #27
Цитата Сообщение от taras atavin Посмотреть сообщение
Лишняя сущность.
Боюсь догадаться о чём это Вы сейчас. Ниже перечислены темы про изнанку С++. Там изнан на изнане на все вкусы. Присмотрите что-нибудь не лишнее.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 15:13  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #28
О дабломаксе конечно.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6444 / 3083 / 306
Регистрация: 04.12.2011
Сообщений: 8,496
Записей в блоге: 4
18.07.2015, 15:17     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #29
Цитата Сообщение от taras atavin Посмотреть сообщение
О дабломаксе конечно.
Это Вы сгоряча.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.07.2015, 15:20     Как вернуть NaN и Infinity, проверить на NaN и Infinity?
Еще ссылки по теме:
C++ Что такое nan?
C++ Nan после вычисления
C++ max [NaN, число] vs max [число, NaN]
При вычисление выдает nan C++
Вывод nan при расчете C++

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.07.2015, 15:20  [ТС]     Как вернуть NaN и Infinity, проверить на NaN и Infinity? #30
Разве? Мне ваще то не нужен максимум дабла. К тому же я ведь могу и поменять тип на float, или на long double. Вот представьте себе: есть некая интовая переменная, надо проверить, равна ли она единице. Вы как проверять будете?
C++
1
if ((x>0)&&(x<2))
?
Yandex
Объявления
18.07.2015, 15:20     Как вернуть NaN и Infinity, проверить на NaN и Infinity?
Ответ Создать тему
Опции темы

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