Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is NaN (Not a Number) in the words of a beginner? [closed]

I still do not understand what a NaN or a (Number which isn´t a real Number) exactly is.

Main question:

  1. What is a NaN value or NaN exactly (in the words of a non-math professor)?

Furthermore i have a few questions about the whole circumstance, which giving me complaints in understanding what a NaN should be, which are not necessary to answer my main question but desired:

  1. What are operations which causing a NaN value as result?

  2. Why is the result of 0.0 / 0.0 declared as undefined? Shouldn´t it be 0?

  3. Why can´t the result of any mathematical operation be expressed by a floating point or integer number? How can it be that a value is unrepresentable?

  4. Why is the square root of a negative number not a real number?

  5. Why is NaN not equivalent to indefinite?

I did not found any understandable explanation of what NaN is for me in the whole Internet, including here on Stack Overflow.


Anyway I want to provide my research as links to places, i have scanned already to find an understandable answer to my question, even if some links go to the same question in other programming languages, but did not gave me the desired clear informations in total:

Wikipedia:

https://en.wikipedia.org/wiki/NaN

https://en.wikipedia.org/wiki/IEEE_754

Other:

http://foldoc.org/Not-a-Number

https://www.youtube.com/watch?v=HN_UmxIVS6M

https://www.youtube.com/watch?v=9EsHjXftO7s

Stack Overflow:

Similar or same questions for other Languages (I provide them as far as i think the base of the understanding is very similar if not the same):

In Java, what does NaN mean?

What is the rationale for all comparisons returning false for IEEE754 NaN values?

(Built-in) way in JavaScript to check if a string is a valid number

JavaScript: what is NaN, Object or primitive?

Not a Number (NaN)

Questions for C++:

What is difference between quiet NaN and signaling NaN?

Checking if a double (or float) is NaN in C++

Why does NaN - NaN == 0.0 with the Intel C++ Compiler?

What is the difference between IND and NAN numbers


Thank you for all helpful answers and comments.

like image 603
RobertS supports Monica Cellio Avatar asked Jan 26 '23 12:01

RobertS supports Monica Cellio


1 Answers

You've asked a series of great questions here. Here's my attempt to address each of them.

What is a NaN value or NaN exactly (in the words of a non-math professor)?

Let's suppose you're working with real numbers - numbers like 1, π, e, -137, 6.626, etc. In the land of real numbers, there are some operations that usually can be performed, but sometimes don't have a defined result. For example, let's look at logarithms. You can take the logarithm of lots of real numbers: ln e = 1, for example, and ln 10 is about 2.3. However, mathematically, the log of a negative number isn't defined. That is, we can't take ln (-4) and get back a real number.

So now, let's jump to programming land. Imagine that you're writing a program that or computes the logarithm of a number, and somehow the user wants you to divide by take the logarithm of a negative number. What should happen?

There's lots of reasonable answers to this question. You could have the operation throw an exception, which is done in some languages like Python.

However, at the level of the hardware the decision that was made (by the folks who designed the IEEE-754 standard) was to give the programmer a second option. Rather than have the program crash, you can instead have the operation produce a value that means "you wanted me to do something impossible, so I'm reporting an error." The way this is done is by having the operation produce the special value NaN ("Not a Number"), indicating that, somewhere in your calculation, you tried to perform an operation that's mathematically not defined.

There are some advantages to this approach. In many scientific computing settings, the code performs a series of long calculations, periodically generating intermediate results that might be of interest. By having operations that aren't defined produce NaN as a result, the programmer can write code that just does the math as they want it to be done, then introduce specific spots in the code where they'll test whether the operation succeeded or not. From there, they can decide what to do. Contrast this with tripping an exception or crashing the program outright - that would mean the programmer either needs to guard every series of floating point operations that could fail or has to manually test things herself. It’s a judgment call about which option is better, which is why you can enable or disable the floating point NaN behavior.

What are operations which causing a NaN value as result?

There are many ways to get a NaN result from an operation. Here's a sampler, though this isn't an exhaustive list:

  1. Taking the log of a negative number.
  2. Taking the square root of a negative number.
  3. Subtracting infinity from infinity.
  4. Performing any arithmetic operation on NaN.

There are, however, some operations that don't produce NaN even though they're mathematically undefined. For example, dividing a positive number by zero gives positive infinity as a result, even though this isn't mathematically defined. The reason for this is that if you take the limit of x / y for positive x as y approaches zero from the positive direction, the value grows without bound.

Why is the result of 0.0 / 0.0 declared as undefined? Shouldn´t it be 0?

This is more of a math question than anything else. This has to do with how limits work. Let's think about how to define 0 / 0. One option would be to say the following: if we look at the expression 0 / x and take the limit as x approaches zero, then we'd see 0 at each point, so the limit should be zero. On the other hand, if we look at the expression x / x and take the limit as x approaches 0, we'd see 1 at each point, so the limit should be one. This is problematic, since we'd like the value of 0 / 0 to be consistent with what you'd find as you evaluated either of these expressions, but we can't pick a fixed value that makes sense. As a result, the value of 0 / 0 gets evaluated as NaN, indicating that there's no clear value to assign here.

Why can´t the result of any mathematical operation be expressed by a floating point or integer number? How can it be that a value is unrepresentable?

This has to do with the internals of IEEE-754 floating point numbers. Intuitively, this boils down to the simple fact that

  1. there are infinitely many real numbers, infinitely many of which have infinitely long non-repeating decimals, but
  2. your computer has finite memory.

As a result, storing an arbitrary real number might entail storing an infinitely long sequence of digits, which we can't do with our finite-memory computers. We therefore have floating point numbers store approximations of real numbers that aren't staggeringly huge, and the inability to represent values results from the fact that we're just storing approximations.

For more on how the numbers are actually stored, and what this means in practice, check out the legendary guide "What Every Programmer Should Know About Floating-Point Arithmetic"

Why is the square root of a negative number not a real number?

Let's take √(-1), for example. Imagine this is a real number x; that is, imagine that x = √(-1). The idea of a square root is that it's a number that, if multiplied by itself, gives you back the number you took the square root of.

So... what number is x? We know that x ≠ 0, because 02 = 0 isn't -1. We also know that x can't be positive, because any positive number times itself is a positive number. And we also know that x can't be negative, because any negative number times itself is positive.

We now have a problem. Whatever this x thing is, it would need to be not positive, not zero, and not negative. That means that it's not a real number.

You can generalize the real numbers to the complex numbers by introducing a number i where i2 = -1. Note that no real numbers do this, for the reason given above.

Why is NaN not equivalent to indefinite?

There's a difference between "indefinite" and "whatever it is, it's not a real number." For example, 0 / 0 may be said to be indeterminate, because depending on how you approach 0 / 0 you might get back 0, or 1, or perhaps something else. On the other hand, √(-1) is perfectly well-defined as a complex number (assuming we have √(-1) give back i rather than -i), so the issue isn't "this is indeterminate" as much as "it's got a value, but that value isn't a real number."

Hope this helps!

like image 142
templatetypedef Avatar answered Apr 01 '23 11:04

templatetypedef