When is a Numeric Result Not a Number?
Quick answer: when the result is a NaN.
Contents
NaNs in Arithmetic
MATLAB has followed the IEEE 754: Standard for Binary Floating-Point Arithmetic for doing arithmetic from the early days, and included tools and functionality to achieve similar results on machines that did not comform to the IEEE standards, e.g., Digital Equipment Corporations VAX computers. In addition, we made choices in MATLAB to allow division by 0 rather than causing an error on machine architectures that could handle this behavior (allowed in the IEEE standard). In allowing division by 0, however, we not only encounter cases in which we divide nonzero positive numbers and negative numbers by 0 (yielding Inf and -Inf respectively, but we also encounter computations that result in undefined mathematical outcomes such as
inf-inf
ans = NaN
0/0
Warning: Divide by zero. ans = NaN
NaNs as Placeholders
In addition to allowing NaN as the result of numeric operations, we've also encouraged their use for marking information such as missing data. If we were gathering some data for some specific times, and missed collecting one of the values, we might end up with data that look like this:
ts = 0:5;
vals = [0.2 4.3 -1.6 NaN -2.0 1.2]
plot(ts,vals,'m*-')
vals = Columns 1 through 5 0.2000 4.3000 -1.6000 NaN -2.0000 Column 6 1.2000
How to Find or Compare to NaN
According to the IEEE standard, NaN is not a number and not equal to anything, including itself. So when looking for NaN values in an array, you can't do the "obvious"
vals == NaN
ans = 0 0 0 0 0 0
As you can see, the comparison is always false. So how do we look for them? Depending on what you are doing, you will find these functions helpful:
Though a mouthful to say or write, isequalwithequalnans allows you to carry out comparisons between arrays matching values and shape, without allowing scalar expansion.
Another way to make look for NaN is frequently cited on the MATLAB newsgroup. See this thread and comments by Paul Bodin for an example. The idea here is that since
NaN == NaN
ans = 0
always produces a false result, we can find NaNs simply by looking for places in which the value doesn't equal itself. These are NaNs, and other values are not.
ourNaNs = vals(vals~=vals)
ourNaNs = NaN
nonNaNs = vals(vals==vals)
nonNaNs = 0.2000 4.3000 -1.6000 -2.0000 1.2000
My preference is to use isnan instead because I find the code much more readable when I revisit it later. However, in some cases, depending on the amount of NaN values (and perhaps other considerations), the constructs just above are sometimes faster. Here are a couple of additional links to newsgroup threads talking more about this.
NaN issues
Some users find themselves experiencing collisions between NaN for missing data vs. NaN as a result of undefined numerical operations.
- Have you encountered such collisions?
- Do you find yourself wishing for more placeholder values?
- What else would you like to use NaN or something similar for?
Let's hear your thoughts.
Published with MATLAB® 7.2
- Category:
- Common Errors,
- Readability