54

Why doesn't infinity comparison follow the logic applied to NaNs? This code prints out false three times:

double a = Double.NaN;
double b = Double.NaN;
System.out.println(a == b); // false
System.out.println(a < b); //  false
System.out.println(a > b); //  false

However, if I change Double.NaN to Double.POSITIVE_INFINITY, I get true for equality, but false for the greater-than and less-than comparisons:

double a = Double.POSITIVE_INFINITY;
double b = Double.POSITIVE_INFINITY;
System.out.println(a == b); // true
System.out.println(a < b); //  false
System.out.println(a > b); //  false

This seems dangerous. Assuming that infinite values result from overflows, I imagine it's more likely that two variables that ended up as infinities wouldn't actually be equal in perfect arithmetic.

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
jck
  • 669
  • 5
  • 9
  • 3
    @giorashc the question is `why is Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY true` – EpicPandaForce Feb 18 '15 at 13:26
  • 1
    disagree that it is a duplicate. This question relates to the POSITIVE_INFINITY side of it and the question is valid. Two infinities are not necessarily equal, especially in a java context where floating point overflow becomes signed infinity. Two operation results could be compared based on this and return true (as both are POSITIVE INFINITY), and yet the results would in practice be different. – Mike Curry Feb 18 '15 at 13:28
  • 1
    @EpicPandaForce, your are correct, retracted the vote – giorashc Feb 18 '15 at 13:28
  • 9
    Regardless of INFINITY: comparing floats or double using `==` is ALWAYS dangerous! – piet.t Feb 18 '15 at 13:51
  • 12
    @piet.t The truth, which is that one should not assume that floating-point computations behave like their mathematical synonyms, is **ALWAYS** stated hyperbolically and wrongly in the way you just did. Floating-point equality is useful in plenty of circumstances, and it is no more dangerous than assignment (also different from how variables behave in maths) or explicit memory management (also different from how things behave in maths). – Pascal Cuoq Feb 18 '15 at 14:46
  • 1
    I wouldn't go so far as to say it's "dangerous", but it's *often not what you mean*. – user253751 Feb 19 '15 at 04:13
  • @PascalCuoq: floating-point computations actually behave quite a lot like their mathematical synonyms, _within the right scope_. Equality comparison of real numbers isn't all that useful either, not in the sense as equality of integers (because _almost all reals are unequal_, in a really quite strong and rigorous sense of the word _almost_). — Variable-assignment or memory management are completely different subjects – indeed not “dangerous” (though many programs _would_ be safer if written in a less mutable style!), but nor are they even analogous to anything that's done in mathematics. – leftaroundabout Feb 19 '15 at 16:01
  • 1
    technically `NaN` is not a value, but `infinity` is a value, comparison is defined by comparing values, from mathematical view-point this doesn't support multiple degrees of infinity, but since overflow is not a mathematical thing, even `infinity` is different from mathematical infinity – Khaled.K Feb 25 '15 at 06:46
  • 4
    Why does anything not behave the same way as a completely different thing? Why would we expect a thing that is NOT a number to be comparable like a number? Great philosophical questions, poor stack overflow questions. – Mark Bolusmjak Feb 25 '15 at 12:17

8 Answers8

70

Your reasoning is that Double.POSITIVE_INFINITY should not be equal to itself because it is “likely” to have been obtained as the result of a loss of accuracy.

This line of reasoning applies to all of floating-point. Any finite value can be obtained as the result of an inaccurate operation. That did not push the IEEE 754 standardization committee to define == as always evaluating to false for finite values, so why should infinities be different?

As defined, == is useful for people who understand what it does (that is, test the floating-point values that have been obtained, and certainly not the values that should have been obtained with real computations). For anyone who understands that, and you need to understand it to use floating-point even for computations that do not involve infinity, having Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY evaluate to true is convenient, if only to test if the floating-point result of a floating-point computation is Double.POSITIVE_INFINITY.

That leaves the question of why NaN can afford to have special behavior, and infinities should follow the same general principles as finite values. NaN is different from infinities: the underlying principle of the IEEE 754 standard is that values are exactly what they are, but the result of an operation can be approximated with respect to the real result, and in this case, the resulting floating-point value is obtained according to the rounding mode.

Forget for an instant that 1.0 / 0.0 is defined as +inf, which is an annoyance in this discussion. Think for the moment of Double.POSITIVE_INFINITY only as the result of operations such as 1.0e100 / 1.0e-300 or Double.MAX_VALUE + Double.MAX_VALUE. For these operations, +inf is the closest approximation of the real result, just like for operations that produce a finite result. By contrast, NaN is the result you obtain when the operation doesn't make sense. It is defensible to have NaN behave specially, but inf is just an approximation of all the values too large to represent.

In reality, 1.0 / 0.0 also produces +inf, but that should be considered an exception. It would have been just as coherent to define the result of that operation as NaN, but defining it as +inf was more convenient in the implementation of some algorithms. An example is provided page 10 in Kahan's notes. More details than most will wish for are in the article “Branch Cuts for Complex Elementary Functions, or Much Ado About Nothing's Sign Bit”. I would also interpret the existence in IEEE 754 of a “division by zero” flag separate from the NaN flag as recognition that the user may want to treat division by zero specially although it is not defined as producing NaN.

Whymarrh
  • 13,139
  • 14
  • 57
  • 108
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • 1
    Interesting, and a fair point. I don't have a compiler in front of me at the moment, wonder what Double.POSITIVE_INFINITY.equals(Double.POSITIVE_INFINITY); returns? Just wondering this because when you think about it Double.POSITIVE_INFINITY will be what is returned from computations and so the behavior of .equals() is what is really interesting as you point out. – Mike Curry Feb 18 '15 at 13:36
  • 1
    @MikeCurry I do not have a computer in front of me either, so it is a fair bet if I take `true` and leave you `false`, right? – Pascal Cuoq Feb 18 '15 at 13:38
  • Wouldnt that mean that System.out.println(a == b) for NaN should be true then? Becuase NaN in both cases is 0x7ff8000000000000L. So that contradicts **test the result of the floating-point values that have been obtained**? – Carlos Bribiescas Feb 18 '15 at 13:40
  • @MikeCurry & Pascal: it returns `true` – posdef Feb 18 '15 at 13:42
  • 2
    @CarlosBribiescas NaN is different from infinities: the underlying principle of the IEEE 754 standard is that values are exactly what they are, but the result of an operation can be approximated wrt the real result, and in this case, the resulting floating-point value is obtained according to the rounding mode. You can obtain an inf as a result of such an approximation: `1.0e100 / 1.0e-300`, for instance. NaN is the result you obtain when the operation doesn't make sense. It is defensible to have NaN behave specially, but inf is just an approximation of all the values too large to represent – Pascal Cuoq Feb 18 '15 at 13:46
  • I think the OPs question is valid in the context of .equals() also then. Just because it could lead to difficult to track down issues. - Maybe that's a different question though. i.e. two calculations return POSITIVE_INFINITY as a result, and the code doesn't check if the result is POSITIVE_INFINITY, but does compare for equality, and takes some action based on this - then that could very well lead to edge cases with problematic side effects. Interesting. – Mike Curry Feb 18 '15 at 13:47
  • @CarlosBribiescas None of this answer is about the representation of values or the fact that NaN has tons of representations or the fact that even identical representations of NaN are different when compared with `==`. – Pascal Cuoq Feb 18 '15 at 13:48
  • @PascalCuoq Thats what I was getting at. Without mentioning the special case, you're solution is incorrect becuase it doesn't compare the result of the floating-point values that have been obtained in all cases. – Carlos Bribiescas Feb 18 '15 at 13:48
  • @PascalCuoq I only mentioned NaN to compare/contrast it to infinity. – Carlos Bribiescas Feb 18 '15 at 13:49
  • @MikeCurry `equals` has to define an equivalence relation, so that weights heavily for all possible floating-point values being `equals` to themselves, even NaN. – Pascal Cuoq Feb 18 '15 at 13:49
  • 1
    Quick update, Pascal is right: `Double.NaN.equals(Double.NaN)` returns true on JDK7 – posdef Feb 18 '15 at 13:53
  • 1
    @CarlosBribiescas … and you referred to one of its representation, which is a completely orthogonal discussion. Anyway, NaN is a special case. Infinities aren't: they approximate values that are too large to represent, for instance when dividing `1.0e100 ` by `1.0e-300`. Since all finite values are also used to represent the result of operations the results of which cannot be represented exactly, there is no reason to treat infinities differently from finite values in the definition of `==`. – Pascal Cuoq Feb 18 '15 at 13:54
  • 1
    @CarlosBribiescas The fact that `1.0 / 0.0` evaluates to inf **is** an exception. The standard would have continued to be quite coherent if that operation had been defined as producing NaN. But there were signed zeroes, and it was convenient for at least one algorithm to define `1.0 / 0.0` as +inf, so that's what was chosen. – Pascal Cuoq Feb 18 '15 at 13:57
  • Thanks - this has been illuminating. – Mike Curry Feb 18 '15 at 13:57
  • @PascalCuoq Its not orthogonal... It adds that == tests exacts values except in special cases, like NaN. When I read your answer, my (maybe incorrect) understanding is that all it does it check bit by bit in every case. – Carlos Bribiescas Feb 18 '15 at 14:00
  • 1
    @CarlosBribiescas I understand that this is what you read in this answer, and this is why I said that this answer is never at any point about the representation of floating-point values. – Pascal Cuoq Feb 18 '15 at 14:02
  • 1
    In addition to this answer, it is actually useful to have all comparisons false as a unique property of NaNs. It gives quick, simple NaN test. – Patricia Shanahan Feb 18 '15 at 14:10
  • 1
    @PatriciaShanahan We have gotten used to testing for NaN with `x != x`, but if NaN had been defined as equal to itself, we would just test it with `x == NaN`. – Pascal Cuoq Feb 18 '15 at 14:28
  • 1
    @PascalCuoq That would have required each NaN to test equal to any NaN, not just itself. Which could have been done, but is a bit more complicated than reflexive equality. – Patricia Shanahan Feb 18 '15 at 14:33
  • _`+inf` is the closest approximation of the real result_: Matematically, any real number is closer to any other real number than `+inf` (/pedantic). – rodrigo Feb 18 '15 at 15:06
  • @rodrigo It depends on your definition of “closer”. In floating-point, the real 0x1.fffffffffffff8p+1023 (written in Java's hexadecimal notation but not a `double`) is at exactly equal distance of +inf and `Double.MAX_VALUE`. Anything below it is closer to `Double.MAX_VALUE`. Anything above it is closer to +inf. – Pascal Cuoq Feb 18 '15 at 15:28
  • 1
    @CarlosBribiescas: `==` tests values, not bit patterns. `+0.0` compares `==` to `-0.0`. – tmyklebu Feb 18 '15 at 15:56
  • Arguably `+0/+0 = +inf`, `-0/+0 = -inf`, etc. – user541686 Feb 18 '15 at 18:38
  • "For these operations, +inf is the closest approximation of the real result, just like for operations that produce a finite result." This is the central point of your post. It would be nice if you reworded or reordered it so that this is closer to the beginning. – jpmc26 Feb 18 '15 at 21:14
  • @rodrigo If you're going to be pedantic, infinity isn't even a number. Talking about "closer to another real than infinity" doesn't even make sense, as infinity isn't even part of that set. Infinity is just a useful way of talking about something that's unbounded (such as a limit, or the size of a set). – jpmc26 Feb 18 '15 at 21:20
  • 1
    @Mehrdad: Having `1/(tinyvalue*tinyvalue)` yield a result that ranks similarly to `(1/tinyvalue)*(1/tinyvalue)` is helpful. IMHO, the weakness in the standard is using the same representation for `(tinyvalue*tinyvalue)`, the constant zero, and the subtraction of equal values. IMHO, branch cuts would have been cleaner had those three values (and negative zero) all been distinct, with `1/(tinyvalue*tinyvalue+0)` yielding +INF, but `1/0`, `1/(1-1)`, and `1/(tinyvalue*tinyvalue+(1-1))` yielding NaN. – supercat Feb 18 '15 at 21:21
  • @PatriciaShanahan: I don't see how the hardware to make NaN values compare unequal to themselves would be any easier than hardware to make the default comparison method regard NaN as equal only to another NaN. Right now it's (BitsEqual or (FirstZero and SecondZero)) and not (FirstNaN or SecondNan). An equivalence relation would be BitsEqual or (FirstZero and SecondZero) or (FirstNaN and SecondNaN). – supercat Feb 18 '15 at 21:29
6

Because thats the standard. Infinity represents a number greater than or less than Double.MAX_VALUE/-Double.MAX_VALUE.

NaN represents the outcome of an operation that didn't make sense. That is, the operation didn't possibly come out with a number.

I would guess the logic is once a number gets big enough (infinity) and because of the limitation of floating point numbers, adding numbers to it won't change the outcome, so its 'like' infinity.

So if you want to compare to really big numbers, at some point you might just say those two big numbers are close enough for all intents and purposes. But if you want to compare two things that both aren't numbers, you can't compare them so its false. At least you couldn't compare them as a primitive.

Carlos Bribiescas
  • 4,197
  • 9
  • 35
  • 66
5

Why are infinities equal? Because it works.

Floating-point arithmetic is designed to produce (relatively) fast computations that preserve errors. The idea being that you don't check for overflows or other nonsense during a lengthy calculation; you wait until it's finished. That's why NaNs propagate the way they do: once you've gotten a NaN, there are very few things you can do that will make it go away. Once the computation is finished you can look for NaNs to check whether something went wrong.

Same for infinities: if there's a possibility of overflow, don't do things that will throw away infinities.

If you want to go slow and safe, IEEE-754 has mechanisms for installing trap handlers to provide callbacks into your code when the result of a calculation would be a NaN or an infinity. Mostly that's not used; it's usually too slow, and pointless once the code has been properly debugged (not that that's easy: people get PhD's in how to do this stuff well).

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
4

Another perspective that justifies "infinite" values being equal is to avoid cardinality concept altogether. Essentially if you cannot speculate on "just how infinite a value is compared to another, given that both are infinite" it's simpler to assume that Inf = Inf.

Edit: as clarification on my comment regarding cardinality I'll give two examples regarding comparison (or equality) of infinite quantities.

Consider the set of positive integers S1 = {1,2,3, ...} , which is infinite. Also consider the set of even integers S2 = {2,4,6, ...}, which are also infinite. While there are clearly twice as many elements in S1 as in S2, they have "equally many" elements since you can easily have a one-to-one function between the sets, i.e. 1 -> 2, 2-> 4, ... They have thus the same cardinality.

Consider instead the set of real numbers R, and the set of integers I. Again both are infinite sets. However for each integer i there are infinitely many real numbers between (i, i+1). Thus no one-to-one function can map the elements of these two sets, and thus their cardinality is different.

Bottomline: equality of infinite quantities is complicated, easier to avoid it in imperative languages :)

posdef
  • 6,498
  • 11
  • 46
  • 94
  • The "infinity" in "R = (-infinity, infinity)" has nothing to do with cardinalities. –  Feb 18 '15 at 16:34
  • @NajibIdrissi not sure what your point is but comparison (or equality) of how infinite quantities have everything to do with cardinality, in theory. I'll add details to make my point more clear. – posdef Feb 19 '15 at 12:27
  • No, you misunderstand what cardinalities represent. They are simply a way to count how many elements are in a set. This doesn't have much to do with comparing "infinities" in the sense of "the limit of x_n is infinity when n goes to infinity", which is a way to say that x_n eventually gets bigger than any number when n grows. Maybe you would be interested in [Hyperreal numbers](https://en.wikipedia.org/wiki/Hyperreal_number) which are a way to formalize, for example, that n^2 grows faster than n. –  Feb 19 '15 at 16:14
  • Infinite sets have undefined cardinality, hence they are infinite. Leibniz determined there are two infinities, the integer infinity and the floating point infinity, i.e. infinite numbers and infinitesimals . It's impossible for a computer to easily determine which type of infinity it is comparing and so it is impossible to say if its equal, less-than, or more than. – Alex Feb 25 '15 at 09:19
3

To me, it seems that "because it should behave the same as zero" would make a good answer. Arithmetic overflow and underflow should be handlable similarly.

If you underflow from the largest near-infinitesimally small value which can be stored in a float, you get zero, and zeros compare as identical.

If you overflow from the largest near-infinitely large value which can be stored in a float, you get INF, and INFs compare as identical.

This means that code which handles numbers which are out-of-scope in both directions will not require separate special-casing for one or the other. Instead, either both or neither will need to be treated differently.

And the simplest requirement is covered by the "neither" case: you want to check if something over/underflowed, you can compare it to zero/INF using just the normal arithmetic comparison operators, without needing to know you current language's special syntax for the checking command: is it Math.isInfinite(), Float.checkForPositiveInfinity(), hasOverflowed()...?

Dewi Morgan
  • 1,143
  • 20
  • 31
  • IMHO, underflow should have yielded "positive infinitesimal" or "negative infinitesimal" values which could arithmetically compare equal to "exact" zero or unsigned zero (the difference between identical finite values other than exact zero); that would have allowed positive and negative values to behave symmetrically, rather than having values indistinguishable from zero be "presumed" positive when performing addition. – supercat Feb 19 '15 at 03:47
  • @supercat While I agree that would be one possible way to handle zero, it wasn't what was done; for the vast majority of uses for which floating point was to be put, it'd be a waste of chip logic. Also, `INF+1=INF`, is still infinity. But `INFIMAL+1=???` Is it `1`? `INFIMAL_PLUS_ONE`? Everything from +INF to -INF should be considered a valid number, so having the vast majority of that number space be invalid because it's INFIMAL away from a specifiable value, would be weird and wrong. With the zero we have, the behavior of INF is the most consistent choice. – Dewi Morgan Feb 19 '15 at 05:48
  • Even if ±INFIMAL existed only around zero, comparison would still make more sense than the terrible "NaN that you can't test with normal test operators" nonsense. It kinda makes sense for NaN to not have numeric operators usable on, since it's not numeric by definition :) – Dewi Morgan Feb 19 '15 at 05:49
  • Adding anything to exact zero would yield exact zero; adding an infinitesimal to one of opposite sign or to unsigned zero would yield unsigned zero; in all other cases, infinitesimals and unsigned zeroes would behave as additive identities. Multiplying *anything* by exact zero would yield exact zero; multiplying unsigned zero or infinitesimal by an infinite value would yield NaN. Multiplying an infinitesimal by a finite positive number would yield an infinitesimal of like sign; multiplying one by a finite negative number would yield an infinitesimal of opposite sign. – supercat Feb 19 '15 at 14:49
  • Basically, infinitesimals would behave like positive and negative zero do now, but additions/subtractions that yield zero would yield an unsigned zero rather than an infinitesimal. Having exact zero behave as an additive identity element and multiplicative zero would allow compilers to replace `x+0.0` with `x` and `0.0*x` with `0.0`, replacements that are not allowable under IEEE-754. It would also mean (-x)+(-y) would equal -(x+y), an equality that presently fails when `x` and `y` are positive and negative zero. – supercat Feb 19 '15 at 15:01
  • So what's 3 + INFIMAL? And if you subtract 3 from that value, what do you get? – Dewi Morgan Feb 21 '15 at 03:32
  • 3.0+PosInfimal==3.0; 3.0-3.0==UnsignedZero. 1.0/UnsignedZero==NaN. The existence of IEEE-754 positive and negative zeroes is designed to ensure that 1/x*1/y will have the same sign as 1/(x*y), but behaves badly with 1/(x-y) and -1/(y-x) [which should be equivalent, but may come out as positive and negative infinity when plugging in the same value for x and y]. Splitting out infinitesimals would eliminate such oddities. – supercat Feb 21 '15 at 16:52
2

The correct answer is a simple "because the standard (and the docs) say so". But I'm not gonna be cynical because it's obvious that's not what you are after.


In addition to the other answers here, I'll try to relate the infinities to saturating arithmetic.

Other answers have already stated that the reason the comparisons on NaNs result in true, so I'm not gonna beat a dead horse.

Let's say I have a saturating integer that represents grayscale colors. Why am I using saturating arithmetic? Because anything brighter than white is still white, and anything darker than black is still black (except orange). That means BLACK - x == BLACK and WHITE + x == WHITE. Makes sense?

Now, let's say we want to represent those grayscale colors with a (signed) 1s complement 8-bit integer where BLACK == -127 and WHITE == 127. Why 1s complement? Because it gives us a signed zero like IEEE 754 floating point. And, because we are using saturating arithmetic, -127 - x == -127 and 127 + x == 127.

How does this relate to floating point infinities? Replace the integer with floating point, BLACK with NEGATIVE_INFINITY, and WHITE with POSITIVE_INFINITY and what do you get? NEGATIVE_INFINITY - x == NEGATIVE_INFINITY and POSITIVE_INFINITY + x == POSITIVE_INFINITY.

Since you used POSITIVE_INFINITY, I'll use it also. First we need a class to represent our saturating integer-based color; let's call it SaturatedColor and assume it works like any other integer in Java. Now, let's take your code and replace double with our own SaturatedColor and Double.POSITIVE_INFINITY with SaturatedColor.WHITE:

SaturatedColor a = SaturatedColor.WHITE;
SaturatedColor b = SaturatedColor.WHITE;

As we established above, SaturatedColor.WHITE (just WHITE above) is 127, so let's do that here:

SaturatedColor a = 127;
SaturatedColor b = 127;

Now we take the System.out.println statements you used and replace a and b with their value (values?):

System.out.println(127 == 127);
System.out.println(127 < 127);
System.out.println(127 > 127);

It should be obvious what this will print.

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
  • An important distinction between saturating arithmetic and infinities is that on most saturating-arithmetic systems, saturated values are treated like non-saturating values when used in subsequent operations, so 120+10-20 would yield 107 rather than 110 or 127. By contrast, operations on infinities simply yield more infinities, except in a few cases where they yield NaN, or in the case of division of a finite number by infinity, which yields a positive or negative zero. – supercat Feb 19 '15 at 00:14
  • @supercat Correct, that's where the analogy breaks down. – Cole Tobin Feb 19 '15 at 04:32
2

Since Double.Nan.equals (Double.NaN) was mentioned: It's one thing what should happen when you perform arithmetic and compare numbers, it's a totally different thing when you consider how objects should behave.

Two typical problem cases are: Sorting an array of numbers, and using hash values to implement dictionaries, sets, and so on. There are two exceptional cases where the normal ordering with <, = and > doesn't apply: One case is that +0 = -0 and the other is that NaN ≠ NaN, and x < NaN, x > NaN, x = NaN will always be false whatever x is.

Sorting algorithms can get into trouble with this. A sorting algorithm may assume that x = x is always true. So if I know that x is stored in an array and look for it, I might not do any bounds check because the search for it must find something. Not if x is NaN. A sorting algorithm may assume that exactly one of a < b and a >= b must be true. Not if one is NaN. So a naive sorting algorithm may crash when NaNs are present. You'd have to decide where you want NaNs to end up when sorting the array, and then change your comparison code so that it works.

Now dictionaries and sets and generally hashing: What if I use an NaN as the key? A set contains unique objects. If the set contains an NaN and I try to add another one, is it unique because it is not equal to the one that is already there? What about +0 and -0, should they be considered equal or different? There's the rule that any two items considered equal must have the same hash value. So the sensible thing is (probably) that a hash function returns one unique value for all NaNs, and one unique value for +0 and -0. And after the hash lookup when you need to find an element with the same hash value that is actually equal, two NaNs should be considered equal (but different from anything else).

That's probably why Double.Nan.equal () behaves different from ==.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • I really wish IEEE-754 had specified that proper implementations must include means for both "mathematical" and "data-processing" comparisons to be performed efficiently (languages could define operators for one kind and two-argument functions for the other); as it is, the standard encourages people to write code which will fail spectacularly when run on data containing a `NaN`, even when acceptable behavior would have been achieved by having `NaN` sort above `PositiveInfinity` or below `NegativeInfinity`, even if `NaN` values produced by some operations went one way and some the other. – supercat Feb 18 '15 at 18:33
  • For example, when running a median to find the 20th and 80th percentiles of a 100-item data set, having a `NaN` in the data set should create some uncertainty as to what those values should be, but only a little bit. Unless sorting code explicitly handles `NaN`, however, it's possible that code might perfectly happily decide to report the 20th percentile as higher than the 80th. – supercat Feb 18 '15 at 18:36
1

This is because NaN is not a number and is therefore not equal to any number including NaN.

Lexicographical
  • 501
  • 4
  • 16
  • 1
    Not sure this addresses the question. The question is related to why the infinity results are treated as equal. Whilst infinities are numbers, the question as to why two infinities would necessarily be considered equal by java is an important one. Even if the answer is just "that's the way it is", it is an important behavior to understand. – Mike Curry Feb 18 '15 at 13:30
  • 1
    Sorry, I didn't mention as to the why. It was defined in the IEEE 754 Floating Point Standard. – Lexicographical Feb 18 '15 at 13:36
  • 7
    If NaN is not a number, how can you speak of "any number including NaN"? – ipsec Feb 18 '15 at 14:20
  • By that, I mean to say that it is not equal to any number. Therefore, it is not a number. Using that perspective, it would not possess a value that could be comparable to a number and does not exactly have a definite value other than that it is not a number. Since it has no definite value, you can't compare it with itself as it would have no definite value so as to speak of. – Lexicographical Feb 19 '15 at 02:32