6 ms·
The comments on this point to another question of which this is an exact duplicate. Interested parties should definitely read the top answer there, as it was wr
by benjamincburns 12y ago
The comments on this point to another question of which this is an exact duplicate. Interested parties should definitely read the top answer there, as it was written by a member of the IEEE-754 committee.
http://stackoverflow.com/a/1573715/203705 http://stackoverflow.com/a/1573715/203705
- stephencanon 12y agoHey, that’s my answer! /wave Strangely, I was just adding some more material to this answer as I’ve never really been completely satisfied with it; then I flip over to hacker news and there it is. Anyway, if anyone has other IEEE-754 questions, I’ll try to answer.
- haberman 12y agoWow, I never would have guessed that a significant reason was historical, so that x != x could provide a robust way to detect NaN without requiring a special API. Is there a similar test for infinity?
- jules 12y agoThat reasoning is incorrect. If they had chosen NaN == NaN, then the test for NaN could be simply x == NaN... The other reason mentioned is also unconvincing. Surely preserving the law x==x is more important than the law x==y <=> x-y==0. Then we have: > Regarding your comment "that doesn't mean that the correct answer is false", this is wrong. The predicate (y < x) asks whether y is less than x. If y is NaN, then it is not less than any floating-point value x, so the answer is necessarily false. Clearly this reasoning is incorrect for the simple reason that the same reasoning can lead to the opposite conclusion. If y is NaN then we can't say that y < x is definitely true but neither can we say that y < x is definitely false. Here is my argument for why NaN == NaN should be true. The == operator for floats should rarely be used. If you want to know whether two floats can be considered the same, then you should always use some other condition like |x-y| < epsilon, and NOT x == y. The reason is that floating point arithmetic is inexact, so even a slight roundoff error will make x == y false. So if its job is not to test whether two floats are the same numerically then what is the job for the == operator? Its job is to test whether x and y are precisely the same float. The x == y operator should not pretend to work on the abstraction that x and y are kinda-sorta real numbers, because such an operator is useless anyway because the criterion for that needs to be application specific. It should compare floats while admitting that we are comparing floats which can take on the value +infinity -infinity +0 -0 and NaN, and we are not comparing real numbers which do not have those values. That's why NaN == NaN should be true.
- stephencanon 12y ago> If they had chosen NaN == NaN, then the test for NaN could be simply x == NaN Not in languages that didn’t have a name for NaN it wouldn’t. > you should always use some other condition like |x-y| < epsilon, and NOT x == y. This is a popular myth, but it is false. There are circumstances in which exact equality comparisons in floating-point are perfectly appropriate. > Its job is to test whether x and y are precisely the same float. No; if it were we would have +0 != -0. You’re looking for totalOrder(x,y) or a related predicate.
- jules 12y ago> Not in languages that didn’t have a name for NaN it wouldn’t. ...then use NaN = 0/0. > This is a popular myth, but it is false. There are circumstances in which exact equality comparisons in floating-point are perfectly appropriate. Can you give an example where == is appropriate, but where you want NaN == NaN to be false? > No; if it were we would have +0 != -0. You’re looking for totalOrder(x,y) or a related predicate. Exactly, +0 == -0 should be false too. totalOrder(x,y) is what == should have been (or at least the equality part of it). p.s. An arguably more serious issue with IEEE floats is rounding modes. The round up/round down modes are tantalizingly close to providing the ability to do ironclad approximate real arithmetic in the sense that you could give upper/lower bounds on the exact value. The problem is that the rounding modes only involve giving an upper/lower bound on the output given an exact input, rather than an upper/lower bound on the output given an upper/lower bound on the input. So it's not compositional which means you can't guarantee anything.
- thedufer 12y ago> ...then use NaN = 0/0. Many languages throw an error when you divide by zero. As far as I can tell, if x != x didn't work you would have to resort to bizarre contortions like `x == float("NaN")` for such tests in Python (the problems: there are no NaN or Infinity constants and division by 0 throws). Also, since you expect == to do bit equality on floats, you will be distinguishing between the huge number of representation of NaN, so NaN = 0/0 isn't valid even if there is a NaN constant (and which one would it be?).
- MaxGabriel 12y agoWhat about it made you not completely satisfied?
- stephencanon 12y agoIt was focused on “how do we approach this sort of decision today” and neglected some of the historical context that informed the decision making. It’s important to consider that the rules for NaN we essentially inherited wholesale from the 8087, which was the proving ground for many of the ideas in IEEE-754.
- benjamincburns 12y agoHa, thanks for chiming in, and for answering that question. It's interactions like this that keep me stupid excited about the internet, and hopeful that someday the ubiquitous, nebulous "they" (as in "they say...") will die.
- dang 12y agoThat seems so much better that we'll just change the url to it. (The original url was http://stackoverflow.com/questions/10034149/why-is-nan-not-equal-to-nan. http://stackoverflow.com/questions/10034149/why-is-nan-not-e...)
- jffry 12y agoThanks for your continued transparency in moderation
- benjamincburns 12y agoAgreed whole-heartedly. Prior to dang's involvement moderation on HN felt a bit like "the invisible hand."
- benjamincburns 12y agoCompletely off topic for the article, but this decision seems, without connotation, a bit heavy handed. I agree with it, actually - it captures the "interestingness" of the thing that the OP posted, but the purist within me reels. If there was any thought process to this change, would you mind sharing it?
- dang 12y agoSure. The short answer is that HN's goal is intellectual curiosity, so that's what we optimize for. Optimizing means trading other things away. One thing we're willing to trade away–if it's a clear win for quality–is fidelity to the original submission. HN's focus should always be on the content, and the details of the original submission are of little interest compared to the subject at hand. Was this particular change a clear win for quality? Well, the new link was better, as was the related subthread, which even included the author of the content, who even served on the relevant IEEE committee, and who was even game to politely bandy about design decisions with strangers superciliously claiming (in the internet's own special way) that he and his colleagues had done their work badly. It's pretty hard to get higher quality than that. HN isn't a purist's kind of place. Our goal to make the front page and the threads as interesting and substantive as possible. We change a lot of things to serve that principle. If we knew how to serve it better, we'd happily break more crockery. Someone (perhaps a purist!) will object that terms like "quality", "interesting", and "substantive" have no precise definitions and are in the eye of the beholder. True, but (a) they're not arbitrary either, (b) the alternatives suck, and (c) someone has to make the calls. We don't get them all right, but we do try hard to correct mistakes, and I'll defend the principle any day.