When does NaN not apply to C ++?

NaN is distributed through the "majority" of operations, as described in NaN - Wikipedia .

I would like to know the operations that NaN does NOT distribute. For example, I am coding in C ++ and found that the following code prints 1 , which is not NaN.

 const double result = std::pow(1, std::numeric_limits<double>::quiet_NaN()); std::cout << result << std::endl; 

For the std::pow function, this behavior is described in std :: pow - cppreference.com .

Could you share with other examples?

+5
source share
3 answers

std::pow not an operator in the sense that something like multiplication in a * b is an operation. This is a function. And functions can have branches that can deal with NaN at their discretion. Another similar function std in a certain sense is std::is_nan . This also does not apply to NaN : it returns a bool , which is implicitly converted to a numeric type:

 std::is_nan(std::is_nan(a)) 

there is false for any type a that allows you to compile the expression. Other examples include std::fpclassify and std::isfinite . I especially like std::fpclassify as an example, since it has an int return type, so it really is no less a numeric function than pow !

Note that the implicit conversion of NaN to bool is defined as false true according to the accepted answer to this question , which is important. He allows ! , && and || work with NaN . Finally, the expression separator operator also does not apply to NaN , while a NaN on an unused branch of a ternary conditional operation is ignored.

+5
source

Otherwise, I would try exp(0, NaN) . If there is exp(0,0) == 1 , then we should expect

  exp(0, NaN) == 1 

There is a rationale for this, and in fact it is necessary for consistent behavior. Despite the lack of an IEEE standard that dictates the behavior of elementary functions with respect to NaN, there is a very basic rule:

If for all finite point numbers x including + inf and -inf (but excluding NaN), we have

 f(const1, x) == const2 

then (and only then) it is also necessary to return the result without NaN

 f(const1, NaN) == const2 

Long explanation

This is because NaN represents "undefined" or "any other numeric value from -inf .. inf". What for? Consider the prototype example 0/0. If you take into account the equation

  b = a * x 

and wants to solve for x . Clear solution

 x = b/a 

Now, if a == b == 0 , then the original equation has an infinite number of solutions, namely, all finite numbers x . This is why NaN means "unspecified" and 0/0 == NaN . Now, if an undefined number (that is, NaN) enters the function as an argument, it most often causes an “unspecified” answer. The exception is that the output is independent of the input, in which case you need / should not return NaN.

Consider

 exp(1, a/b) 

This expression is always evaluated as 1 for nonzero a and b , which makes sense from a mathematical point of view, since 1^x in the mathematical sense does not depend on x . So it would also be required numerically for a = 0 or b = 0 (and therefore x=NaN ) to get 1 as well.

So, if you accept that

 pow(1,-inf) = pow(1,inf) = 1 

it is also necessary to determine

 pow(1,NaN) = 1 

for consistent behavior. The same applies to pow(0,c) , but also an estimate of the polynomial of degree zero should generate a non-NaN output at the input of NaN.

Note: this reasoning can be applied to any function, including built-in operators.

+3
source

Here is an example that demonstrates NaN functions that return non-NaN. The list is specified in IEEE 754-2008, 9.2.1 Special Values ​​(there are some other functions, but they don't seem to be implemented in C ++):

 #include <cmath> #include <limits> #include <iostream> int main() { const auto nan=std::numeric_limits<double>::quiet_NaN(); const auto inf=std::numeric_limits<double>::infinity(); std::cout << std::hypot(nan,inf) << '\n'; std::cout << std::hypot(inf,nan) << '\n'; std::cout << std::pow(nan, 0) << '\n'; std::cout << std::pow(1,nan) << '\n'; } 

Output:

 inf inf 1 1 
+2
source

Source: https://habr.com/ru/post/1275662/


All Articles