有 isnan() 函数吗?
PS.:我在MinGW(如果这有什么不同的话)。
我通过使用 isnan() from 解决了这个问题<math.h>
,它在 中不存在<cmath>
,我一开始是在#include
ing 中。
根据 IEEE 标准,NaN 值具有奇数特性,即涉及它们的比较总是错误的。也就是说,对于浮点数 f,仅当 f 为 NaN时才f != f
为真。
请注意,正如下面的一些评论所指出的,并非所有编译器在优化代码时都尊重这一点。
对于任何声称使用 IEEE 浮点的编译器,这个技巧应该可以工作。但我不能保证它会在实践中发挥作用。如果有疑问,请检查您的编译器。
isnan()
当前 C++ 标准库中没有可用的函数。它是在C99中引入的,并被定义为宏而不是函数。C99 定义的标准库元素不是当前 C++ 标准 ISO/IEC 14882:1998 的一部分,也不是其更新 ISO/IEC 14882:2003 的一部分。
2005 年提出了技术报告 1。TR1 为 C++ 带来了与 C99 的兼容性。尽管事实上它从未被正式采用成为 C++ 标准,但许多(GCC 4.0+或Visual C++ 9.0+ C++ 实现确实提供了 TR1 特性,全部或仅提供一些特性(Visual C++ 9.0 不提供 C99 数学函数) .
如果 TR1 可用,则cmath
包括 C99 元素,如isnan()
,isfinite()
等,但它们通常在std::tr1::
命名空间中定义为函数,而不是宏,尽管许多实现(即 Linux 上的 GCC 4+ 或 Mac OS X 10.5+ 上的 XCode)注入它们直接到std::
,所以std::isnan
定义明确。
此外,C++ 的一些实现仍然使 C99isnan()
宏可用于 C++(通过cmath
or包含math.h
),这可能会导致更多的混淆,开发人员可能会认为这是一种标准行为。
关于 Viusal C++ 的注释,如上所述,它std::isnan
既不提供std::tr1::isnan
,但提供了定义为自Visual C++ 6.0_isnan()
以来可用的扩展函数
在 XCode 上,还有更多的乐趣。如前所述,GCC 4+ 定义了std::isnan
. 对于旧版本的编译器和库形式的 XCode,似乎(这里是相关讨论),没有机会检查自己)__inline_isnand()
在 Intel 和__isnand()
Power PC 上定义了两个函数。
既然有人问了这个问题,就有了一些新的发展:重要的是要知道这std::isnan()
是 C++11 的一部分
在标题中定义<cmath>
bool isnan( float arg ); (since C++11)
bool isnan( double arg ); (since C++11)
bool isnan( long double arg ); (since C++11)
确定给定的浮点数 arg 是否不是数字 ( NaN
)。
参数
arg
: 浮点值
返回值
true
如果 arg 是NaN
,false
否则
参考
http://en.cppreference.com/w/cpp/numeric/math/isnan
请注意,如果您使用 g++,这与 -fast-math 不兼容,请参阅下面的其他建议。
对于 C99,在 C 中,这被实现为isnan(c)
返回 int 值的宏。的类型x
应为浮点型、双精度型或长双精度型。
不同的供应商可能包含也可能不包含或不包含某个功能isnan()
。
据称可移植的检查方法是使用不等于自身NaN
的 IEEE 754 属性:即 ie将是false 。NaN
x == x
x
NaN
但是,最后一个选项可能不适用于每个编译器和某些设置(特别是优化设置),因此在最后的手段中,您始终可以检查位模式......
Boost 中还有一个仅包含标头的库,它具有处理浮点数据类型的简洁工具
#include <boost/math/special_functions/fpclassify.hpp>
您将获得以下功能:
template <class T> bool isfinite(T z);
template <class T> bool isinf(T t);
template <class T> bool isnan(T t);
template <class T> bool isnormal(T t);
如果您有时间,请查看 Boost 的整个数学工具包,它有许多有用的工具并且正在快速增长。
此外,在处理浮点数和非浮点数时,查看Numeric Conversions可能是个好主意。
共有三种“官方”方式:posixisnan
宏、c++0xisnan
函数模板或可视化 c++_isnan
函数。
不幸的是,检测使用哪些是相当不切实际的。
不幸的是,没有可靠的方法来检测您是否具有带有 NaN 的 IEEE 754 表示。标准库提供了官方的这种方式(numeric_limits<double>::is_iec559
)。但在实践中,诸如 g++ 之类的编译器搞砸了。
理论上可以简单地使用x != x
,但是像 g++ 和 visual c++ 这样的编译器会把它搞砸。
所以最后,测试特定的NaN 位模式,假设(并希望在某个时候强制执行!)特定的表示,例如 IEEE 754。
编辑:作为“诸如 g++ 之类的编译器……搞砸”的一个例子,考虑
#include <limits>
#include <assert.h>
void foo( double a, double b )
{
assert( a != b );
}
int main()
{
typedef std::numeric_limits<double> Info;
double const nan1 = Info::quiet_NaN();
double const nan2 = Info::quiet_NaN();
foo( nan1, nan2 );
}
使用 g++ (TDM-2 mingw32) 4.4.1 编译:
C:\test> 键入“C:\Program Files\@commands\gnuc.bat” @rem -finput-charset=windows-1252 @g++ -O -pedantic -std=c++98 -Wall -Wwrite-strings %* -Wno-long-long C:\test> gnuc x.cpp C:\test> 一个 && 回声工作... || 回声!失败 作品... C:\test> gnuc x.cpp --fast-math C:\test> 一个 && 回声工作... || 回声!失败 断言失败:a != b,文件 x.cpp,第 6 行 此应用程序已请求运行时以不寻常的方式终止它。 请联系应用程序的支持团队以获取更多信息。 !失败的 C:\测试> _
如果您的编译器支持 c99 扩展,则有一个 std::isnan,但我不确定 mingw 是否支持。
如果您的编译器没有标准功能,这是一个应该可以工作的小功能:
bool custom_isnan(double var)
{
volatile double d = var;
return d != d;
}
您可以使用标准库中numeric_limits<float>::quiet_NaN( )
定义的limits
来进行测试。为 定义了一个单独的常量double
。
#include <iostream>
#include <math.h>
#include <limits>
using namespace std;
int main( )
{
cout << "The quiet NaN for type float is: "
<< numeric_limits<float>::quiet_NaN( )
<< endl;
float f_nan = numeric_limits<float>::quiet_NaN();
if( isnan(f_nan) )
{
cout << "Float was Not a Number: " << f_nan << endl;
}
return 0;
}
我不知道这是否适用于所有平台,因为我只在 Linux 上使用 g++ 进行了测试。
您可以使用该isnan()
函数,但您需要包含 C 数学库。
#include <cmath>
由于此功能是 C99 的一部分,因此并非随处可用。如果您的供应商不提供该功能,您也可以定义自己的变体以实现兼容性。
inline bool isnan(double x) {
return x != x;
}
从 C++14 开始,有多种方法可以测试浮点数value
是否为 NaN。
在这些方法中,只有检查数字表示的位才能可靠地工作,如我原来的答案中所述。特别std::isnan
是经常提出的检查v != v
,不能可靠地工作,不应该使用,以免当有人决定需要浮点优化时你的代码停止正常工作,并要求编译器这样做。这种情况可以改变,编译器可以变得更加符合,但是对于这个问题,自从最初的答案以来已经 6 年没有发生过。
大约 6 年来,我最初的答案是这个问题的选定解决方案,这没问题。v != v
但最近选择了一个推荐不可靠测试的高度赞成的答案。因此,这个额外的更新的答案(我们现在有 C++11 和 C++14 标准,以及即将到来的 C++17)。
从 C++14 开始,检查 NaN 的主要方法是:
std::isnan(value) )
是自 C++11 以来预期的标准库方式。isnan
显然与同名的 Posix 宏冲突,但实际上这不是问题。主要问题是,当请求浮点算术优化时,至少使用一个主编译器,即 g++,std::isnan
返回false
NaN 参数。
(fpclassify(value) == FP_NAN) )
遇到与 相同的问题std::isnan
,即不可靠。
(value != value) )
在许多 SO 答案中推荐。遇到与 相同的问题std::isnan
,即不可靠。
(value == Fp_info::quiet_NaN()) )
这是一个测试,标准行为不应该检测到 NaN,但优化行为可能可以检测到 NaN(由于优化的代码只是直接比较位级表示),并且可能结合另一种方法来覆盖标准的未优化行为,可以可靠地检测到 NaN。不幸的是,结果证明它不能可靠地工作。
(ilogb(value) == FP_ILOGBNAN) )
遇到与 相同的问题std::isnan
,即不可靠。
isunordered(1.2345, value) )
遇到与 相同的问题std::isnan
,即不可靠。
is_ieee754_nan( value ) )
这不是标准功能。它根据 IEEE 754 标准检查位。它是完全可靠的,但代码有点依赖于系统。
在下面的完整测试代码中,“成功”是表达式是否报告值的 Nan-ness。对于大多数表达式,这种衡量成功的方法、检测 NaN 和仅检测 NaN 的目标对应于它们的标准语义。然而,对于(value == Fp_info::quiet_NaN()) )
表达式,标准行为是它不能用作 NaN 检测器。
#include <cmath> // std::isnan, std::fpclassify
#include <iostream>
#include <iomanip> // std::setw
#include <limits>
#include <limits.h> // CHAR_BIT
#include <sstream>
#include <stdint.h> // uint64_t
using namespace std;
#define TEST( x, expr, expected ) \
[&](){ \
const auto value = x; \
const bool result = expr; \
ostringstream stream; \
stream << boolalpha << #x " = " << x << ", (" #expr ") = " << result; \
cout \
<< setw( 60 ) << stream.str() << " " \
<< (result == expected? "Success" : "FAILED") \
<< endl; \
}()
#define TEST_ALL_VARIABLES( expression ) \
TEST( v, expression, true ); \
TEST( u, expression, false ); \
TEST( w, expression, false )
using Fp_info = numeric_limits<double>;
inline auto is_ieee754_nan( double const x )
-> bool
{
static constexpr bool is_claimed_ieee754 = Fp_info::is_iec559;
static constexpr int n_bits_per_byte = CHAR_BIT;
using Byte = unsigned char;
static_assert( is_claimed_ieee754, "!" );
static_assert( n_bits_per_byte == 8, "!" );
static_assert( sizeof( x ) == sizeof( uint64_t ), "!" );
#ifdef _MSC_VER
uint64_t const bits = reinterpret_cast<uint64_t const&>( x );
#else
Byte bytes[sizeof(x)];
memcpy( bytes, &x, sizeof( x ) );
uint64_t int_value;
memcpy( &int_value, bytes, sizeof( x ) );
uint64_t const& bits = int_value;
#endif
static constexpr uint64_t sign_mask = 0x8000000000000000;
static constexpr uint64_t exp_mask = 0x7FF0000000000000;
static constexpr uint64_t mantissa_mask = 0x000FFFFFFFFFFFFF;
(void) sign_mask;
return (bits & exp_mask) == exp_mask and (bits & mantissa_mask) != 0;
}
auto main()
-> int
{
double const v = Fp_info::quiet_NaN();
double const u = 3.14;
double const w = Fp_info::infinity();
cout << boolalpha << left;
cout << "Compiler claims IEEE 754 = " << Fp_info::is_iec559 << endl;
cout << endl;;
TEST_ALL_VARIABLES( std::isnan(value) ); cout << endl;
TEST_ALL_VARIABLES( (fpclassify(value) == FP_NAN) ); cout << endl;
TEST_ALL_VARIABLES( (value != value) ); cout << endl;
TEST_ALL_VARIABLES( (value == Fp_info::quiet_NaN()) ); cout << endl;
TEST_ALL_VARIABLES( (ilogb(value) == FP_ILOGBNAN) ); cout << endl;
TEST_ALL_VARIABLES( isunordered(1.2345, value) ); cout << endl;
TEST_ALL_VARIABLES( is_ieee754_nan( value ) );
}
使用 g++ 的结果(再次注意,它的标准行为(value == Fp_info::quiet_NaN())
是它不能用作 NaN 检测器,它在这里非常具有实际意义):
[C:\my\forums\so\282(检测 NaN)] > g++ --版本 | 找到“++” g++ (x86_64-win32-sjlj-rev1, 由 MinGW-W64 项目构建) 6.3.0 [C:\my\forums\so\282(检测 NaN)] > g++ foo.cpp && a 编译器声称 IEEE 754 = true v = nan, (std::isnan(value)) = true 成功 u = 3.14, (std::isnan(value)) = false 成功 w = inf, (std::isnan(value)) = false 成功 v = nan, ((fpclassify(value) == 0x0100)) = true 成功 u = 3.14, ((fpclassify(value) == 0x0100)) = false 成功 w = inf, ((fpclassify(value) == 0x0100)) = false 成功 v = nan, ((value != value)) = true 成功 u = 3.14, ((value != value)) = false 成功 w = inf, ((value != value)) = false 成功 v = nan, ((value == Fp_info::quiet_NaN())) = false 失败 u = 3.14, ((value == Fp_info::quiet_NaN())) = false 成功 w = inf, ((value == Fp_info::quiet_NaN())) = false 成功 v = nan, ((ilogb(value) == ((int)0x80000000))) = true 成功 u = 3.14, ((ilogb(value) == ((int)0x80000000))) = false 成功 w = inf, ((ilogb(value) == ((int)0x80000000))) = false 成功 v = nan, (isunordered(1.2345, value)) = true 成功 u = 3.14, (isunordered(1.2345, value)) = false 成功 w = inf, (isunordered(1.2345, value)) = false 成功 v = nan, (is_ieee754_nan( value )) = true 成功 u = 3.14, (is_ieee754_nan( value )) = false 成功 w = inf, (is_ieee754_nan( value )) = false 成功 [C:\my\forums\so\282(检测 NaN)] > g++ foo.cpp -ffast-math && a 编译器声称 IEEE 754 = true v = nan, (std::isnan(value)) = false 失败 u = 3.14, (std::isnan(value)) = false 成功 w = inf, (std::isnan(value)) = false 成功 v = nan, ((fpclassify(value) == 0x0100)) = false 失败 u = 3.14, ((fpclassify(value) == 0x0100)) = false 成功 w = inf, ((fpclassify(value) == 0x0100)) = false 成功 v = nan, ((value != value)) = false 失败 u = 3.14, ((value != value)) = false 成功 w = inf, ((value != value)) = false 成功 v = nan, ((value == Fp_info::quiet_NaN())) = true 成功 u = 3.14, ((value == Fp_info::quiet_NaN())) = true 失败 w = inf, ((value == Fp_info::quiet_NaN())) = true 失败 v = nan, ((ilogb(value) == ((int)0x80000000))) = true 成功 u = 3.14, ((ilogb(value) == ((int)0x80000000))) = false 成功 w = inf, ((ilogb(value) == ((int)0x80000000))) = false 成功 v = nan, (isunordered(1.2345, value)) = false 失败 u = 3.14, (isunordered(1.2345, value)) = false 成功 w = inf, (isunordered(1.2345, value)) = false 成功 v = nan, (is_ieee754_nan( value )) = true 成功 u = 3.14, (is_ieee754_nan( value )) = false 成功 w = inf, (is_ieee754_nan( value )) = false 成功 [C:\my\forums\so\282(检测 NaN)] > _
Visual C++ 的结果:
[C:\my\forums\so\282(检测 NaN)] > cl /nologo- 2>&1 | 找到“++” Microsoft (R) C/C++ 优化编译器版本 19.00.23725 for x86 [C:\my\forums\so\282(检测 NaN)] > cl foo.cpp /Feb && b foo.cpp 编译器声称 IEEE 754 = true v = nan, (std::isnan(value)) = true 成功 u = 3.14, (std::isnan(value)) = false 成功 w = inf, (std::isnan(value)) = false 成功 v = nan, ((fpclassify(value) == 2)) = true 成功 u = 3.14, ((fpclassify(value) == 2)) = false 成功 w = inf, ((fpclassify(value) == 2)) = false 成功 v = nan, ((value != value)) = true 成功 u = 3.14, ((value != value)) = false 成功 w = inf, ((value != value)) = false 成功 v = nan, ((value == Fp_info::quiet_NaN())) = false 失败 u = 3.14, ((value == Fp_info::quiet_NaN())) = false 成功 w = inf, ((value == Fp_info::quiet_NaN())) = false 成功 v = nan, ((ilogb(value) == 0x7fffffff)) = true 成功 u = 3.14, ((ilogb(value) == 0x7fffffff)) = false 成功 w = inf, ((ilogb(value) == 0x7fffffff)) = true 失败 v = nan, (isunordered(1.2345, value)) = true 成功 u = 3.14, (isunordered(1.2345, value)) = false 成功 w = inf, (isunordered(1.2345, value)) = false 成功 v = nan, (is_ieee754_nan( value )) = true 成功 u = 3.14, (is_ieee754_nan( value )) = false 成功 w = inf, (is_ieee754_nan( value )) = false 成功 [C:\my\forums\so\282(检测 NaN)] > cl foo.cpp /Feb /fp:fast && b foo.cpp 编译器声称 IEEE 754 = true v = nan, (std::isnan(value)) = true 成功 u = 3.14, (std::isnan(value)) = false 成功 w = inf, (std::isnan(value)) = false 成功 v = nan, ((fpclassify(value) == 2)) = true 成功 u = 3.14, ((fpclassify(value) == 2)) = false 成功 w = inf, ((fpclassify(value) == 2)) = false 成功 v = nan, ((value != value)) = true 成功 u = 3.14, ((value != value)) = false 成功 w = inf, ((value != value)) = false 成功 v = nan, ((value == Fp_info::quiet_NaN())) = false 失败 u = 3.14, ((value == Fp_info::quiet_NaN())) = false 成功 w = inf, ((value == Fp_info::quiet_NaN())) = false 成功 v = nan, ((ilogb(value) == 0x7fffffff)) = true 成功 u = 3.14, ((ilogb(value) == 0x7fffffff)) = false 成功 w = inf, ((ilogb(value) == 0x7fffffff)) = true 失败 v = nan, (isunordered(1.2345, value)) = true 成功 u = 3.14, (isunordered(1.2345, value)) = false 成功 w = inf, (isunordered(1.2345, value)) = false 成功 v = nan, (is_ieee754_nan( value )) = true 成功 u = 3.14, (is_ieee754_nan( value )) = false 成功 w = inf, (is_ieee754_nan( value )) = false 成功 [C:\my\forums\so\282(检测 NaN)] > _
总结上述结果,仅使用is_ieee754_nan
此测试程序中定义的函数直接测试位级表示,在 g++ 和 Visual C++ 的所有情况下都可靠地工作。
附录:
在发布上述内容后,我意识到另一种可能测试 NaN 的方法,在此处的另一个答案中提到,即((value < 0) == (value >= 0))
. 事实证明,这在 Visual C++ 上工作得很好,但在 g++ 的-ffast-math
选项下失败了。只有直接位模式测试才能可靠地工作。
以下代码使用 NAN 的定义(所有指数位设置,至少一个小数位设置)并假设 sizeof(int) = sizeof(float) = 4。您可以在 Wikipedia 中查找 NAN 以获取详细信息。
bool IsNan( float value )
{
return ((*(UINT*)&value) & 0x7fffffff) > 0x7f800000;
}
我对这个问题的回答是不要对nan
. 改为使用预防性检查来检查表格的各个部分0.0/0.0
。
#include <float.h>
float x=0.f ; // I'm gonna divide by x!
if( !x ) // Wait! Let me check if x is 0
x = FLT_MIN ; // oh, since x was 0, i'll just make it really small instead.
float y = 0.f / x ; // whew, `nan` didn't appear.
nan
运算的结果0.f/0.f
,或0.0/0.0
。 nan
是代码稳定性的可怕克星,必须非常小心地检测和防止1 . 其性质nan
与普通数不同:
nan
有毒,(5* nan
= nan
)nan
不等于任何东西,甚至不等于自身 ( nan
!= nan
)nan
不大于任何东西(nan
!> 0)nan
不小于任何东西 ( nan
!< 0)列出的最后 2 个属性是反逻辑的,将导致依赖于与nan
数字比较的代码的奇怪行为(倒数第三个属性也是奇数,但您可能永远不会x != x ?
在代码中看到(除非您正在检查对于nan(不可靠)))。
在我自己的代码中,我注意到nan
值往往会产生难以发现的错误。(请注意,对于or而言,情况并非如此。 ( < 0) 返回, ( 0 < ) 返回 TRUE,甚至 ( < ) 返回 TRUE。因此,根据我的经验,代码的行为通常仍符合预期)。inf
-inf
-inf
TRUE
inf
-inf
inf
你想要发生的事情0.0/0.0
必须作为一个特殊情况来处理,但你所做的事情必须取决于你期望从代码中得出的数字。
在上面的例子中, ( 0.f/FLT_MIN
)的结果0
基本上是 。您可能想要0.0/0.0
生成HUGE
。所以,
float x=0.f, y=0.f, z;
if( !x && !y ) // 0.f/0.f case
z = FLT_MAX ; // biggest float possible
else
z = y/x ; // regular division.
因此,在上面,如果 x 是0.f
,inf
将导致(实际上如上所述,它具有非常好的/非破坏性行为)。
请记住,整数除以 0 会导致运行时异常。因此,您必须始终检查整数除以 0。仅仅因为0.0/0.0
悄悄地评估为nan
并不意味着您可以懒惰并且0.0/0.0
在它发生之前不检查。
1检查nan
viax != x
有时是不可靠的(x != x
被一些破坏 IEEE 合规性的优化编译器剥离,特别-ffast-math
是在启用开关时)。
inline bool IsNan(float f)
{
const uint32 u = *(uint32*)&f;
return (u&0x7F800000) == 0x7F800000 && (u&0x7FFFFF); // Both NaN and qNan.
}
inline bool IsNan(double d)
{
const uint64 u = *(uint64*)&d;
return (u&0x7FF0000000000000ULL) == 0x7FF0000000000000ULL && (u&0xFFFFFFFFFFFFFULL);
}
如果sizeof(int)
为 4 且sizeof(long long)
为 8,则此方法有效。
在运行期间,它只是比较,铸件不需要任何时间。它只是更改比较标志配置以检查相等性。
不依赖于所用 NaN 的特定 IEEE 表示的可能解决方案如下:
template<class T>
bool isnan( T f ) {
T _nan = (T)0.0/(T)0.0;
return 0 == memcmp( (void*)&f, (void*)&_nan, sizeof(T) );
}
考虑到 NaN 并不总是保证 (x != x) (例如,如果使用 -ffast-math 选项),我一直在使用:
#define IS_NAN(x) (((x) < 0) == ((x) >= 0))
数字不能同时为 < 0 和 >= 0,所以实际上只有当数字既不小于、也不大于或等于零时,此检查才会通过。这基本上根本就不是数字,或者是 NaN。
如果您愿意,也可以使用它:
#define IS_NAN(x) (!((x)<0) && !((x)>=0)
我不确定这如何受到 -ffast-math 的影响,因此您的里程可能会有所不同。
至于我,解决方案可能是一个宏,使其显式内联,因此速度足够快。它也适用于任何浮点类型。它基于这样一个事实,即值不等于自身的唯一情况是值不是数字时。
#ifndef isnan
#define isnan(a) (a != a)
#endif
这有效:
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
char ch='a';
double val = nan(&ch);
if(isnan(val))
cout << "isnan" << endl;
return 0;
}
输出:伊斯南
在我看来,最好的真正跨平台方法是使用联合并测试双精度的位模式以检查 NaN。
我还没有彻底测试过这个解决方案,并且可能有一种更有效的方式来处理位模式,但我认为它应该可以工作。
#include <stdint.h>
#include <stdio.h>
union NaN
{
uint64_t bits;
double num;
};
int main()
{
//Test if a double is NaN
double d = 0.0 / 0.0;
union NaN n;
n.num = d;
if((n.bits | 0x800FFFFFFFFFFFFF) == 0xFFFFFFFFFFFFFFFF)
{
printf("NaN: %f", d);
}
return 0;
}
IEEE 标准规定,当指数全为1
s 且尾数不为零时,数字为 a NaN
。Double 是1
符号位、11
指数位和52
尾数位。做一点检查。
正如上面的评论所说 a != a 在 g++ 和其他一些编译器中不起作用,但是这个技巧应该。它可能效率不高,但它仍然是一种方式:
bool IsNan(float a)
{
char s[4];
sprintf(s, "%.3f", a);
if (s[0]=='n') return true;
else return false;
}
基本上,在 g++ 中(我不确定其他人)如果变量不是有效的整数/浮点数,printf 会在 %d 或 %.f 格式上打印“nan”。因此,此代码检查字符串的第一个字符是否为“n”(如“nan”)
这通过检查它是否在双重限制内来检测 Visual Studio 中的无穷大和 NaN:
//#include <float.h>
double x, y = -1.1; x = sqrt(y);
if (x >= DBL_MIN && x <= DBL_MAX )
cout << "DETECTOR-2 of errors FAILS" << endl;
else
cout << "DETECTOR-2 of errors OK" << endl;