Why Does Nan^0 == 1

Why does NaN^0 == 1

This is referenced in the help page referenced by ?'NaN'

"The IEC 60559 standard, also known as the ANSI/IEEE 754 Floating-Point Standard.

http://en.wikipedia.org/wiki/NaN."

And there you find this statement regarding what should create a NaN:

 "There are three kinds of operations that can return NaN:[5]
Operations with a NaN as at least one operand.

It is probably is from the particular C compiler, as signified by the Note you referenced. This is what the GNU C documentation says:

http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html

" NaN, on the other hand, infects any calculation that involves it. Unless the calculation would produce the same result no matter what real value replaced NaN, the result is NaN."

So it seems that the GNU-C people have a different standard in mind when writing their code. And the 2008 version of ANSI/IEEE 754 Floating-Point Standard is reported to make that suggestion:

http://en.wikipedia.org/wiki/NaN#Function_definition

The published standard is not free. So if you are have access rights or money you can look here:

http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933

In Java, what does NaN mean?

Taken from this page:

"NaN" stands for "not a number". "Nan"
is produced if a floating point
operation has some input parameters
that cause the operation to produce
some undefined result. For example,
0.0 divided by 0.0 is arithmetically undefined. Taking the square root of a
negative number is also undefined.

Why is NaN not equal to NaN?

My original answer (from 4 years ago) criticizes the decision from the modern-day perspective without understanding the context in which the decision was made. As such, it doesn't answer the question.

The correct answer is given here:

NaN != NaN originated out of two pragmatic considerations:

[...] There was no isnan( ) predicate at the time that NaN was formalized in the 8087 arithmetic; it was necessary to provide programmers with a convenient and efficient means of detecting NaN values that didn’t depend on programming languages providing something like isnan( ) which could take many years

There was one disadvantage to that approach: it made NaN less useful in many situations unrelated to numerical computation. For example, much later when people wanted to use NaN to represent missing values and put them in hash-based containers, they couldn't do it.

If the committee foresaw future use cases, and considered them important enough, they could have gone for the more verbose !(x<x & x>x) instead of x!=x as a test for NaN. However, their focus was more pragmatic and narrow: providing the best solution for a numeric computation, and as such they saw no issue with their approach.

===

Original answer:

I am sorry, much as I appreciate the thought that went into the top-voted answer, I disagree with it. NaN does not mean "undefined" - see http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF, page 7 (search for the word "undefined"). As that document confirms, NaN is a well-defined concept.

Furthermore, IEEE approach was to follow the regular mathematics rules as much as possible, and when they couldn't, follow the rule of "least surprise" - see https://stackoverflow.com/a/1573715/336527. Any mathematical object is equal to itself, so the rules of mathematics would imply that NaN == NaN should be True. I cannot see any valid and powerful reason to deviate from such a major mathematical principle (not to mention the less important rules of trichotomy of comparison, etc.).

As a result, my conclusion is as follows.

IEEE committee members did not think this through very clearly, and made a mistake. Since very few people understood the IEEE committee approach, or cared about what exactly the standard says about NaN (to wit: most compilers' treatment of NaN violates the IEEE standard anyway), nobody raised an alarm. Hence, this mistake is now embedded in the standard. It is unlikely to be fixed, since such a fix would break a lot of existing code.

Edit: Here is one post from a very informative discussion. Note: to get an unbiased view you have to read the entire thread, as Guido takes a different view to that of some other core developers. However, Guido is not personally interested in this topic, and largely follows Tim Peters recommendation. If anyone has Tim Peters' arguments in favor of NaN != NaN, please add them in comments; they have a good chance to change my opinion.

Why does it show nan?

First your while condition should be
while((fabs(next - value))> accuracy) and fact should return long double.
When you change that it still won't work for value of 45. The reason is that this Taylor series converge too slowly for large values.
Here is the error term in the formula

Sample Image

Here k is the number of iterations a=0 and the function is sin.In order for the condition to become false 45^(k+1)/(k+1)! times some absolute value of sin or cos (depending what the k-th derivative is) (it's between 0 and 1) should be less than 0.0001.
Well in this formula for value of 50 the number is still very large (we should expect error of around 1.3*10^18 which means we will do more than 50 iterations for sure).
45^50 and 50! will overflow and then dividing them will give you infinity/infinity=NAN.
In your original version fact value doesn't fit in the integer (your value overflows to 0) and then the division over 0 gives you infinity which after subtract of another infinity gives you NAN.

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

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!

A surprise with 1**math.nan and 0j**math.nan

Quoting this question which in turns quotes IEEE 754 (see Wikipedia),

The 2008 version of the IEEE 754 standard says that pow(1,qNaN) and pow(qNaN,0) should both return 1 since they return 1 whatever else is used instead of quiet NaN.

For details see page 56 of IEEE 754 2008:

pow(x, ±0) is 1 for any x (even a zero, quiet NaN, or infinity)

pow(±0, y) is ±∞ and signals the divideByZero exception for y an odd

Thus, the reasoning seems to be that no matter what number k is in the exponent, 1^k = 1, 1^Nan should also be 1. Why that reasoning is reasonable (I'm sure it is) I'll need to dig further.

Personally, I think this makes sense - Nan doesn't really exist in math, it's just that our floating point representation can't handle it (or, Nan is "the computation is too much, this is some number but not sure which"). Thus, 1^Nan could be 1 to an arbitrary power (not 1 to something that is not a number), but since the answer will always be 1, it can only help if we define 1^Nan to be 1.

In JavaScript, why does zero divided by zero return NaN, but any other divided by zero return Infinity?

Because that's how floating-point is defined (more generally than just Javascript). See for example:

  • http://en.wikipedia.org/wiki/Floating-point#Infinities
  • http://en.wikipedia.org/wiki/NaN#Creation

Crudely speaking, you could think of 1/0 as the limit of 1/x as x tends to zero (from the right). And 0/0 has no reasonable interpretation at all, hence NaN.

Preventing NaN when dividing zero with value

When dividing, say x / y, you can get four outcomes (providing that neither x nor y is NaN, +Inf, Inf):

     0   when            y != 0 -- <- expected
+Inf x > 0 and y == 0
-Inf x < 0 and y == 0
NaN x == 0 and y == 0 -- <- actual

So in your case - NaN when computing

  float value = getCurrentSpeed() / getMaxSpeed()

we can conclude that both getCurrentSpeed() and getMaxSpeed() are zeros and you have to test getMaxSpeed() for being 0

what does NaN mean for doubles?

From Wikipedia :

In computing, NaN (Not a Number) is a value of the numeric data type representing an undefined or unrepresentable value, especially in floating-point calculations. Systematic use of NaNs was introduced by the IEEE 754 floating-point standard in 1985, along with the representation of other non-finite quantities like infinities.

And from MSDN :

  • Represents a value that is not a number (NaN). This field is constant.

  • The value of this constant is the result of dividing zero by zero.

  • This constant is returned when the result of an operation is undefined.

  • Use IsNaN to determine whether a value is not a number. It is not possible to determine whether a value is not a number by comparing it to another value equal to NaN.

Where as Infinity (positive infinity and negative infinity) is the result of a floating point operation that causes an overflow (For example 3.0 / 0).



Related Topics



Leave a reply



Submit