Deliberately using NaN in Fortran - fortran

I've read the informative posts on NaN use in Fortran comparisons (here and here)
and I think I've got a handle on roughly what's going on.
My question is more about NaN use in general.
Say I have a collection of reals and I don't know, yet, what their values are. So I set them all to be NaN and, effectively, I use NaN to mean, in part, 'unallocated'. There seems to be some debate as to whether this is a good idea and I've read recommendations to use huge(1.0) or some other 'magic number' instead.
But using NaN seems to have real benefits in that that any calculation involving any variable of value NaN will result in a NaN. Which is helpful (and probably 'correct' in a mathematical sense).
For example if x is set to NaN, and y is 1.23 then
z = x + y
z = x - y
z = x * y
z = x / y
will always result in z being NaN (at least it does with Intel v18 on Windows) - which is what I want: z is unknown because x is unknown.
So - is this an acceptable use of NaN? Or am I creating problems that I'm not aware of yet?

You can do that automatically in many compilers with switches like -finit-real. It can be useful, that's why they supply this switch. Many compilers offer this.
Note that there are two kinds of NaN. A quiet NaN and a signalling NaN. Usage of he signalling NaN will trigger a floating point exception.
Whether it to preferred over a different sentinel value is pretty much just an opinion, so I will not answer that, opinion based questions and polls are off-topic here. We cannot really continue here in the debate you linked (Is it a good idea to use IEEE754 floating point NaN for values which are not set?). I don't think it is a good SO question in today's standards (notice how old it is!), and many of those answers wouldn't stand today, but if anyone has something more to add, they can do that in that question, no point raising it here.

Related

In Haskell, [0.1..1] returns [0.1,1.1]. Why? [duplicate]

This question already has answers here:
Haskell ranges and floats
(2 answers)
Closed 1 year ago.
I am finding the list of [0.1..1] that will be returned from Haskell and I do not understand why it is [0.1,1.1]. Can anyone provide explanation for me please?
TL;DR: don't use [x..y] on floating point numbers. You might get unexpected results.
On floating point numbers, there's no sane semantics for [x..y]. For instance, one might argue that the semantics should be [x,x+1,x+2,...,x+n] where x+n is the largest value of that form which is <=y. However, this does not account for floating point rounding errors. It is possible that x+n produces a slightly larger value than the exact y, making the list shorter than expected. Hence this semantics makes the value of length [x..y] rather unpredictable.
Haskell tries to mitigate this issue, by allowing an error up to 0.5. The rationale is as follows: when x+n is closer to y than to y+1, it should be regarded as some value in the interval [x..y] which got rounded to something larger. Arguable, but this is how Haskell works.
In enumerations like [x,y .. z] with an explicit stepping (e.g. [0.0,5.0 .. 1000.0]) Haskell instead allows an error of (y-x)/2 (2.5 in the example). The rationale is the same: we include those points which are closer to 1000 than to 1000+5.
You can find all the gory details in the Haskell Report which defines the semantics of Haskell. This part is also relevant.
This is generally seen by Haskellers as a small wart in the language. Some argue that we should not have mandated Enum Float and Enum Double. Removing those instances would effectively prohibit the troublesome cases like [1.0 .. 5.0] or the much worse [1.0 .. 5.5] (which is again numerically unstable).

There are 2 kinds of NaN: signaling_NaN, quiet_NaN, and... NAN itself?

I always thought there were 2 kinds of NaN's: quiet and signaling.
But then I realized the NAN macro evaluates to neither.
In Visual C++, std::numeric_limits<float>::quiet_NaN() is displayed as 1.#QNAN000.
In Visual C++, std::numeric_limits<float>::signaling_NaN() is displayed as 1.#QNAN000.
Yet also in Visual C++, NAN is displayed as -1.#IND0000... which is neither of the above.
What kind of NaN, then, is the NAN constant? Is it signaling or nonsignaling?
When should I use NAN instead of the others, when should I avoid it, and why?
You machine does not have a signaling NaN. I presume the Q in #QNAN stands for Quiet. Check numeric_limits::has_signaling_NaN. As for signaling_NaN, the standard says this:
Meaningful for all specializations for which has_signaling_NaN != false. Required in specializations
for which is_iec559 != false.
Therefore, it may be required yet meaningless… the natural thing to do is supply a quiet NaN instead.
I haven't found an authoritative resource for QNAN vs IND, but they appear to both be quiet NaNs. There are potentially millions of different NaNs, one for each mantissa value. If I were to guess, IND may be like an error code for an ind‍eterminate value, e.g. 0/0. Not really an appropriate choice for a generic NAN macro, but they might have been stuck with it after defining the C numeric binding that way.

C++ float number to nan

I want to know what makes a float number nan in c++. I am using a large dataset and it is really hard to trace. I want to know the ways of changing a float number to nan to reduce bug possibilities.
I found the code that causes the nan problem. I found that s/m is nan in some cases. But I don't know how to solve it.
float gp(float x){
float e = 2.71828183;
x *= -1;
float s = pow(e,x);
float m = (1 + pow(e,x)) * (1 + pow(e,x));
return s / m;}
Taken from wikipedia -> special values -> nan
0/0
∞×0
sqrt(−1)
in general "invalid operations" (I am not sure wether there are not more than the three above)
Looking at you code: infinity times 0 is possible, is it?
edit:
0 <= s <= +inf
1 <= m <= +inf
s / m:
+inf / +inf does indeed make minus NaN (I tested it)
I think that's the only thing that makes a NaN.
If you can keep x between 0 and FLT_MAX (3.40E+38 in my case), your gp function will not return NaN.
You say in a comment that you only use *, +, -.
[Edit: you've since said that you also use pow and division, which introduce some extra ways to get NaN. For example if the parameter x is a large negative value then pow(e,-x) is infinity, so you can easily end up computing infinity/infinity, which is another NaN]
So, if you have IEEE floating-point then assuming this summary is correct, the only ways you can generate NaN are:
Generate a positive or negative infinity by going out of range,
Multiply it by zero.
or:
Generate a positive and a negative infinity,
Add them (or equivalently, subtract two infinities of the same sign).
So if you check for and catch infinities, you don't have to worry about NaNs as well. That said, the usual way is to let such values propagate as quiet NaNs, and check at the end.
For C++ implementations using non-IEEE arithmetic, I'm not sure what the rules are when a NaN is permitted. I could look them up in the standard, but then again so could you ;-)
sqrt(-1)
give you NaN, for example.
http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html
EDIT Try use double instead of float.
Probably it depends to compiler you using but general option is:
variable is too small
variable is too big
divide by 0 (zero)
This is exactly the use case for enabling and trapping floating-point exceptions. That way you can detect exactly where the NaN (or other exception value) first appears.
However, that's a platform-dependant feature, so you may have to look into the documentation of your compiler and/or hardware.

What does -1.#IND00 mean? [duplicate]

I'm messing around with some C code using floats, and I'm getting 1.#INF00, -1.#IND00 and -1.#IND when I try to print floats in the screen. What does those values mean?
I believe that 1.#INF00 means positive infinity, but what about -1.#IND00 and -1.#IND? I also saw sometimes this value: 1.$NaN which is Not a Number, but what causes those strange values and how can those help me with debugging?
I'm using MinGW which I believe uses IEEE 754 representation for float point numbers.
Can someone list all those invalid values and what they mean?
From IEEE floating-point exceptions in C++ :
This page will answer the following questions.
My program just printed out 1.#IND or 1.#INF (on Windows) or nan or inf (on Linux). What happened?
How can I tell if a number is really a number and not a NaN or an infinity?
How can I find out more details at runtime about kinds of NaNs and infinities?
Do you have any sample code to show how this works?
Where can I learn more?
These questions have to do with floating point exceptions. If you get some strange non-numeric output where you're expecting a number, you've either exceeded the finite limits of floating point arithmetic or you've asked for some result that is undefined. To keep things simple, I'll stick to working with the double floating point type. Similar remarks hold for float types.
Debugging 1.#IND, 1.#INF, nan, and inf
If your operation would generate a larger positive number than could be stored in a double, the operation will return 1.#INF on Windows or inf on Linux. Similarly your code will return -1.#INF or -inf if the result would be a negative number too large to store in a double. Dividing a positive number by zero produces a positive infinity and dividing a negative number by zero produces a negative infinity. Example code at the end of this page will demonstrate some operations that produce infinities.
Some operations don't make mathematical sense, such as taking the square root of a negative number. (Yes, this operation makes sense in the context of complex numbers, but a double represents a real number and so there is no double to represent the result.) The same is true for logarithms of negative numbers. Both sqrt(-1.0) and log(-1.0) would return a NaN, the generic term for a "number" that is "not a number". Windows displays a NaN as -1.#IND ("IND" for "indeterminate") while Linux displays nan. Other operations that would return a NaN include 0/0, 0*∞, and ∞/∞. See the sample code below for examples.
In short, if you get 1.#INF or inf, look for overflow or division by zero. If you get 1.#IND or nan, look for illegal operations. Maybe you simply have a bug. If it's more subtle and you have something that is difficult to compute, see Avoiding Overflow, Underflow, and Loss of Precision. That article gives tricks for computing results that have intermediate steps overflow if computed directly.
For anyone wondering about the difference between -1.#IND00 and -1.#IND (which the question specifically asked, and none of the answers address):
-1.#IND00
This specifically means a non-zero number divided by zero, e.g. 3.14 / 0 (source)
-1.#IND (a synonym for NaN)
This means one of four things (see wiki from source):
1) sqrt or log of a negative number
2) operations where both variables are 0 or infinity, e.g. 0 / 0
3) operations where at least one variable is already NaN, e.g. NaN * 5
4) out of range trig, e.g. arcsin(2)
Your question "what are they" is already answered above.
As far as debugging (your second question) though, and in developing libraries where you want to check for special input values, you may find the following functions useful in Windows C++:
_isnan(), _isfinite(), and _fpclass()
On Linux/Unix you should find isnan(), isfinite(), isnormal(), isinf(), fpclassify() useful (and you may need to link with libm by using the compiler flag -lm).
For those of you in a .NET environment the following can be a handy way to filter non-numbers out (this example is in VB.NET, but it's probably similar in C#):
If Double.IsNaN(MyVariableName) Then
MyVariableName = 0 ' Or whatever you want to do here to "correct" the situation
End If
If you try to use a variable that has a NaN value you will get the following error:
Value was either too large or too small for a Decimal.

What do 1.#INF00, -1.#IND00 and -1.#IND mean?

I'm messing around with some C code using floats, and I'm getting 1.#INF00, -1.#IND00 and -1.#IND when I try to print floats in the screen. What does those values mean?
I believe that 1.#INF00 means positive infinity, but what about -1.#IND00 and -1.#IND? I also saw sometimes this value: 1.$NaN which is Not a Number, but what causes those strange values and how can those help me with debugging?
I'm using MinGW which I believe uses IEEE 754 representation for float point numbers.
Can someone list all those invalid values and what they mean?
From IEEE floating-point exceptions in C++ :
This page will answer the following questions.
My program just printed out 1.#IND or 1.#INF (on Windows) or nan or inf (on Linux). What happened?
How can I tell if a number is really a number and not a NaN or an infinity?
How can I find out more details at runtime about kinds of NaNs and infinities?
Do you have any sample code to show how this works?
Where can I learn more?
These questions have to do with floating point exceptions. If you get some strange non-numeric output where you're expecting a number, you've either exceeded the finite limits of floating point arithmetic or you've asked for some result that is undefined. To keep things simple, I'll stick to working with the double floating point type. Similar remarks hold for float types.
Debugging 1.#IND, 1.#INF, nan, and inf
If your operation would generate a larger positive number than could be stored in a double, the operation will return 1.#INF on Windows or inf on Linux. Similarly your code will return -1.#INF or -inf if the result would be a negative number too large to store in a double. Dividing a positive number by zero produces a positive infinity and dividing a negative number by zero produces a negative infinity. Example code at the end of this page will demonstrate some operations that produce infinities.
Some operations don't make mathematical sense, such as taking the square root of a negative number. (Yes, this operation makes sense in the context of complex numbers, but a double represents a real number and so there is no double to represent the result.) The same is true for logarithms of negative numbers. Both sqrt(-1.0) and log(-1.0) would return a NaN, the generic term for a "number" that is "not a number". Windows displays a NaN as -1.#IND ("IND" for "indeterminate") while Linux displays nan. Other operations that would return a NaN include 0/0, 0*∞, and ∞/∞. See the sample code below for examples.
In short, if you get 1.#INF or inf, look for overflow or division by zero. If you get 1.#IND or nan, look for illegal operations. Maybe you simply have a bug. If it's more subtle and you have something that is difficult to compute, see Avoiding Overflow, Underflow, and Loss of Precision. That article gives tricks for computing results that have intermediate steps overflow if computed directly.
For anyone wondering about the difference between -1.#IND00 and -1.#IND (which the question specifically asked, and none of the answers address):
-1.#IND00
This specifically means a non-zero number divided by zero, e.g. 3.14 / 0 (source)
-1.#IND (a synonym for NaN)
This means one of four things (see wiki from source):
1) sqrt or log of a negative number
2) operations where both variables are 0 or infinity, e.g. 0 / 0
3) operations where at least one variable is already NaN, e.g. NaN * 5
4) out of range trig, e.g. arcsin(2)
Your question "what are they" is already answered above.
As far as debugging (your second question) though, and in developing libraries where you want to check for special input values, you may find the following functions useful in Windows C++:
_isnan(), _isfinite(), and _fpclass()
On Linux/Unix you should find isnan(), isfinite(), isnormal(), isinf(), fpclassify() useful (and you may need to link with libm by using the compiler flag -lm).
For those of you in a .NET environment the following can be a handy way to filter non-numbers out (this example is in VB.NET, but it's probably similar in C#):
If Double.IsNaN(MyVariableName) Then
MyVariableName = 0 ' Or whatever you want to do here to "correct" the situation
End If
If you try to use a variable that has a NaN value you will get the following error:
Value was either too large or too small for a Decimal.