What the NaN?
-
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Max(); // Infinity
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Min(); // NaN
var isNaNSmaller = double.NaN < 1; // falseSo NaN is not the biggest value, it's still bigger than one, but it's also the smallest value. I hate to sound infinitely negative, but that's messed up :wtf:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
Mmm, naan bread, just like granny used to make.
veni bibi saltavi
-
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Max(); // Infinity
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Min(); // NaN
var isNaNSmaller = double.NaN < 1; // falseSo NaN is not the biggest value, it's still bigger than one, but it's also the smallest value. I hate to sound infinitely negative, but that's messed up :wtf:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Interesting; imho that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function. I am relieved to know that in .NET C# double.PositiveInfinity == double.NegativeInfinity => 'false, since, if that returned 'true, I would assume my system is now a conscious entity ... in which case it would certainly be planning to kill me in league with the various cpu's in my home appliances. Be careful, Sander, it was the contemplation of the mathematics of the ordinality of infinities (the aleph) that drove both Cantor, and Godel, insane. cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
This has nothing to do with C#. I refer you to IEEE 754.
I'm glad that a lot of people have thought about how NaN should have contradictory results in different usages :doh: <Edit> So it seems the contradictory result are in IEEE 754, but the weird behavior in Min and Max is Microsoft[^] :laugh: </Edit>
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Richard MacCutchan wrote:
So you cannot equate it to any numeric value
Yes you can, and that's the point. I expected either an exception (compile or run time) or at least a predictable weird behavior (well, it's predictable once you know all the edge cases I guess). Now whether you should is a different discussion... :) I found this because I had some weird JavaScript bug by the way, casting some object to a number results in NaN and I was wondering how C# handled the case the followed. NaN is not smaller than 1 (when comparing and when using the Min function), but when both are thrown into the Max function NaN is smaller than 1. Got it :~ Luckily, I've never had to work with NaN in C# because why would there even be a NaN anyway...
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Interesting; imho that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function. I am relieved to know that in .NET C# double.PositiveInfinity == double.NegativeInfinity => 'false, since, if that returned 'true, I would assume my system is now a conscious entity ... in which case it would certainly be planning to kill me in league with the various cpu's in my home appliances. Be careful, Sander, it was the contemplation of the mathematics of the ordinality of infinities (the aleph) that drove both Cantor, and Godel, insane. cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
BillWoodruff wrote:
that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function
Actually, it doesn't. Both Min and Max treat NaN as the smallest value. However, when comparing NaN to any other value it's both bigger and smaller.
BillWoodruff wrote:
it was the contemplation of the mathematics of the ordinality of infinities (the aleph) that drove both Cantor, and Godel, insane
It was mathematics that drove me insane in high school . And then again at University. And then again at another University... :sigh:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
In WPF you can set the width of certain visual components to Double.NaN. This is interpreted by .NET to mean "width is set to auto". At least that is how I remember the use for Double.NaN
Get me coffee and no one gets hurt!
I guess "Auto" would be one example of NaN :laugh:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Richard MacCutchan wrote:
So you cannot equate it to any numeric value
Yes you can, and that's the point. I expected either an exception (compile or run time) or at least a predictable weird behavior (well, it's predictable once you know all the edge cases I guess). Now whether you should is a different discussion... :) I found this because I had some weird JavaScript bug by the way, casting some object to a number results in NaN and I was wondering how C# handled the case the followed. NaN is not smaller than 1 (when comparing and when using the Min function), but when both are thrown into the Max function NaN is smaller than 1. Got it :~ Luckily, I've never had to work with NaN in C# because why would there even be a NaN anyway...
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
Sander Rossel wrote:
why would there even be a NaN anyway...
- 0/0
- ∞/∞
- ∞+(-∞)
- √-1
- and so on...
Just because you are not familiar with the subject, does not make others wrong.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
-
Interesting; imho that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function. I am relieved to know that in .NET C# double.PositiveInfinity == double.NegativeInfinity => 'false, since, if that returned 'true, I would assume my system is now a conscious entity ... in which case it would certainly be planning to kill me in league with the various cpu's in my home appliances. Be careful, Sander, it was the contemplation of the mathematics of the ordinality of infinities (the aleph) that drove both Cantor, and Godel, insane. cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
BillWoodruff wrote:
that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function.
I doubt it there is different treatment, it's just different implementation of if condition. For instance, Min method could have this condition:
if (currentMin > values[i])
currentMin = values[i];and Max this one:
if (!(currentMax > values[i]))
currentMax = values[i];If Max was implemented in this way:
if (currentMax < values[i])
currentMax = values[i];it would return
NaN
also. edit: I'll be damned. NaN indeed has different treatment in Min method. Comment from the source code[^]:// Normally NaN < anything is false, as is anything < NaN
// However, this leads to some irksome outcomes in Min and Max.
// If we use those semantics then Min(NaN, 5.0) is NaN, but
// Min(5.0, NaN) is 5.0! To fix this, we impose a total
// ordering where NaN is smaller than every value, including
// negative infinity.
if (x < value || System.Single.IsNaN(x)) value = x;GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
-
Sander Rossel wrote:
why would there even be a NaN anyway...
- 0/0
- ∞/∞
- ∞+(-∞)
- √-1
- and so on...
Just because you are not familiar with the subject, does not make others wrong.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
0/0 should throw a DivideByZeroException (which it does for integers). And apparently 1/0 equals infinity. Now what is it? NaN, infinity or just plain not possible? Doesn't it sound weird (and, indeed, very wrong) that a NUMERIC type has a value "NOT A NUMBER"!? Anyway, when I said "why would there even be a NaN anyway" I was referring to NaN in actual real life business cases that make sense and have practical use :)
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Max(); // Infinity
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Min(); // NaN
var isNaNSmaller = double.NaN < 1; // falseSo NaN is not the biggest value, it's still bigger than one, but it's also the smallest value. I hate to sound infinitely negative, but that's messed up :wtf:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
Comparing a floating point value with NaN always returns false (an "unordered result"; even when both operands are NaN). This can be seen at your 3rd test. With the
Min()
code, all values are checked if they are smaller than the others. Because comparing with NaN is always false, no other element is detected as smaller and the check retunrs NaN. With theMax()
code the values are compared to be greater which always fails for NaN. See also NaN - Wikipedia, the free encyclopedia[^]. -
0/0 should throw a DivideByZeroException (which it does for integers). And apparently 1/0 equals infinity. Now what is it? NaN, infinity or just plain not possible? Doesn't it sound weird (and, indeed, very wrong) that a NUMERIC type has a value "NOT A NUMBER"!? Anyway, when I said "why would there even be a NaN anyway" I was referring to NaN in actual real life business cases that make sense and have practical use :)
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
I would recommend you to this article before you continue your rant about IEEE754.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
-
Comparing a floating point value with NaN always returns false (an "unordered result"; even when both operands are NaN). This can be seen at your 3rd test. With the
Min()
code, all values are checked if they are smaller than the others. Because comparing with NaN is always false, no other element is detected as smaller and the check retunrs NaN. With theMax()
code the values are compared to be greater which always fails for NaN. See also NaN - Wikipedia, the free encyclopedia[^].So it's completely dependent on the internals of Min and Max. Had Max checked if any values were smaller than the current then NaN would always be max and had Min checked if any values were greater than the current then NaN would never be min. So change your implementation and NaN will behave differently, feels very random.
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Max(); // Infinity
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Min(); // NaN
var isNaNSmaller = double.NaN < 1; // falseSo NaN is not the biggest value, it's still bigger than one, but it's also the smallest value. I hate to sound infinitely negative, but that's messed up :wtf:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Max(); // Infinity
var result = new[] { 1, double.PositiveInfinity, double.NegativeInfinity, double.NaN }.Min(); // NaN
var isNaNSmaller = double.NaN < 1; // falseSo NaN is not the biggest value, it's still bigger than one, but it's also the smallest value. I hate to sound infinitely negative, but that's messed up :wtf:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
Here's the reasoning from the source code[^]:
// Normally NaN < anything is false, as is anything < NaN // However, this leads to some irksome outcomes in Min and Max. // If we use those semantics then Min(NaN, 5.0) is NaN, but // Min(5.0, NaN) is 5.0! To fix this, we impose a total // ordering where NaN is smaller than every value, including // negative infinity.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
-
I would recommend you to this article before you continue your rant about IEEE754.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
Tried to read it once, but to me it makes as much sense as the whole NaN implementation: none whatsoever (and I admit my limited math skills are to blame). However, I tried reading the NaN part and what they basically say is that in some edge cases you don't want computations to stop (throw exceptions) when some bogus values are inserted (e.g. divide by 0). The workaround without NaN would be to catch exceptions and simply try again. Unfortunately, every language handles exceptions differently so they standardized on NaN. Awesome, they destroyed our numeric system to support some edge cases (correct me if I'm wrong) :D Luckily .NET offers some sensible numeric types with int, long and decimal :D Unfortunately, I'm currently working in JavaScript, with floating point arithmetic, where NaN is quite common, and 0.1 + 0.2 equals 0.30000000000000004 (yes, I know that's IEEE754, but that doesn't make it right) :sigh:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Here's the reasoning from the source code[^]:
// Normally NaN < anything is false, as is anything < NaN // However, this leads to some irksome outcomes in Min and Max. // If we use those semantics then Min(NaN, 5.0) is NaN, but // Min(5.0, NaN) is 5.0! To fix this, we impose a total // ordering where NaN is smaller than every value, including // negative infinity.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
Thanks, good find! At least that clears that up! :D
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
Here's the reasoning from the source code[^]:
// Normally NaN < anything is false, as is anything < NaN // However, this leads to some irksome outcomes in Min and Max. // If we use those semantics then Min(NaN, 5.0) is NaN, but // Min(5.0, NaN) is 5.0! To fix this, we impose a total // ordering where NaN is smaller than every value, including // negative infinity.
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
By the way, the email for this message had a YouTube link attached to it. I just found it in your sig :laugh: And I would once again argue that the existence of NaN is just plain wrong. Well, at least you're right about the Lounge ;p
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
BillWoodruff wrote:
that implies the treatment of double.NaN in the 'Min function is different than in the 'Max function.
I doubt it there is different treatment, it's just different implementation of if condition. For instance, Min method could have this condition:
if (currentMin > values[i])
currentMin = values[i];and Max this one:
if (!(currentMax > values[i]))
currentMax = values[i];If Max was implemented in this way:
if (currentMax < values[i])
currentMax = values[i];it would return
NaN
also. edit: I'll be damned. NaN indeed has different treatment in Min method. Comment from the source code[^]:// Normally NaN < anything is false, as is anything < NaN
// However, this leads to some irksome outcomes in Min and Max.
// If we use those semantics then Min(NaN, 5.0) is NaN, but
// Min(5.0, NaN) is 5.0! To fix this, we impose a total
// ordering where NaN is smaller than every value, including
// negative infinity.
if (x < value || System.Single.IsNaN(x)) value = x;GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
Mladen Janković wrote:
I'll be damned. NaN indeed has different treatment
Oh my, are you saying that my post actually meant something ? If that's the case, I hereby offer you enough plenary indulgence to be un-damned ... once you have voted.
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
Richard MacCutchan wrote:
So you cannot equate it to any numeric value
Yes you can, and that's the point. I expected either an exception (compile or run time) or at least a predictable weird behavior (well, it's predictable once you know all the edge cases I guess). Now whether you should is a different discussion... :) I found this because I had some weird JavaScript bug by the way, casting some object to a number results in NaN and I was wondering how C# handled the case the followed. NaN is not smaller than 1 (when comparing and when using the Min function), but when both are thrown into the Max function NaN is smaller than 1. Got it :~ Luckily, I've never had to work with NaN in C# because why would there even be a NaN anyway...
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
To my mind, the only reasonable operations with NaN are assigning an lvalue to NaN and comparing a value to NaN for equality and inequality. Any of the arithmetic operators ought to yield NaN (or throw an exception). Come to think of it, the IEEE must have a formal document that describes all of this behavior. Pardon me while I JFGI... Ahh; typical. The formal document is only available to IEEE members who know the official circle jerk handshake. NaN - Wikipedia, the free encyclopedia[^] is a quick article that describes background and informally NaN's usage. This article: IEEE Standard 754 Floating-Point[^] also has some discussion on NaN behavior.
Software Zen:
delete this;