What the NaN?
-
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
That is true. But keep in mind that the Min and Max functions have nothing to do with C# - they are written in C#; yes, but they are part of the LINQ / the .NET Framework. The difference in both is that Max excludes NaN, while Min will take NaN exclusively. You can see the difference here (Min)[^] and here (Max)[^]. That is different to some JS functions (such as everything in Math), which are defined by the same specification as the language.
-
Hi Mladen, DateTime.Now.Ticks "is the number of 100-nanosecond intervals that have elapsed since 1/1/0001, 12:00am." Yes: if you had a loop calling that function faster than 100 ns., you could get a duplicate seed, and what you suggest is better practice. If "heavier-duty randomness" were required I would use the Crypto library. In real-world code, I would create a single static instance of 'Random, and re-use it. I wrote that code while I was half-dead, although that's a very poor excuse :) 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:
I wrote that code while I was half-dead, although that's a very poor excuse :)
Not if you're actually Schrödinger's Bill! :omg:
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
-
The behaviour of comparing with Nan is defined. The implementation of Min and Max is probably not. But a Min function is usually implemented as x < y ? x : y instead of !(x >= y) ? x : y Overall, comparing with NaN makes no sense as already noted by others. Just change the order of your elements (e.g. NaN as first element).
Jochen Arndt wrote:
The implementation of Min and Max is probably not. But a Min function is usually implemented as x < y ? x : y instead of !(x >= y) ? x : y
Actually Min and Max don't treat NaN as they should to get predictable results, as pointed out by Mladen :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
-
Did you know that both
1 < double.NaN
and1 > double.NaN
are false?! ;PA new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!
I know, which makes its behavior in Min and Max even more random :D Although, as it turns out, it's not random at all. Min and Max just treat NaN as lower than anything else.
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
-
NaN means Not a Number, so you cannot compare it to a proper number and get a valid response.
And with that the case is more than closed. :thumbsup:
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver When I was six, there were no ones and zeroes - only zeroes. And not all of them worked. -- Ravi Bhavnani
-
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
You need to check for NaN before passing to min/max and eventually root out them by code. What happened to the simple rule of checking for unexpected/invalid values before using them? Does everybody now cross the streets without looking, eventually launching an exception if hit by a car?
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver When I was six, there were no ones and zeroes - only zeroes. And not all of them worked. -- Ravi Bhavnani
-
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
-
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
-
Sander Rossel wrote:
And apparently 1/0 equals infinity.
No, it does not, and never has.
double x = 1;
double y = 0;
double z = x / y; // InfinityYes it does :~ I'm not making this stuff up, you know (IEEE does that).
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
-
double x = 1;
double y = 0;
double z = x / y; // InfinityYes it does :~ I'm not making this stuff up, you know (IEEE does that).
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
-
Jochen Arndt wrote:
The implementation of Min and Max is probably not. But a Min function is usually implemented as x < y ? x : y instead of !(x >= y) ? x : y
Actually Min and Max don't treat NaN as they should to get predictable results, as pointed out by Mladen :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
I don't saw Mladen's reply when I wrote mine (late in the night) but it explains what happens here. But that implementation produces predictible results: If an element is NaN, it is the smallest number and returned. How should it be treated else? The only other option from my point of view would be throwing an execption (e.g. by using signaling NaNs instead of quite NaNs).
-
No it doesn't, 1/0 is undefined (i.e NaN) and always has been. Various computer systems may try to represent it by some very large or very small value, but that does not alter the fact that it has no mathematical value.
Really man, I completely agree with you there, but .NET (and I guess IEEE) represents 1 / 0 as Infinity and 0 / 0 as NaN. And Infinity behaves different than NaN, so they're not the same (according to .NET/IEEE) no matter what we think of it :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
-
Really man, I completely agree with you there, but .NET (and I guess IEEE) represents 1 / 0 as Infinity and 0 / 0 as NaN. And Infinity behaves different than NaN, so they're not the same (according to .NET/IEEE) no matter what we think of it :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
-
You need to check for NaN before passing to min/max and eventually root out them by code. What happened to the simple rule of checking for unexpected/invalid values before using them? Does everybody now cross the streets without looking, eventually launching an exception if hit by a car?
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver When I was six, there were no ones and zeroes - only zeroes. And not all of them worked. -- Ravi Bhavnani
den2k88 wrote:
What happened to the simple rule of checking for unexpected/invalid values before using them?
Now you're talking a religion of which I am a true believer ! So many questions on C# QA could be answered by the posters, themselves, if they had learned to check input values before calling them, and how to use a debugger. I am also in favor of disabling, or hiding, UI controls that are irrelevant to the current context, or which would create errors if clicked, or, which should only be used after specific action(s) by the user.
«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
-
I know, so always treat it as smallest value, or always as biggest value or, better yet, throw an exception when comparing it to numbers. These results are contradictory and just don't make any sense at all! :~ If this was JavaScript I'd be okay with it, but we're talking C# here. I expected better from C# :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
Sander Rossel wrote:
so always treat it as smallest value, or always as biggest value or, better yet, throw an exception when comparing it to numbers.
If you know you have a scenario where NaN is in play, then test for the NaN and handle accordingly? You should not let a NaN produce an exception on purpose? Maybe I am not getting the big deal here, because I don't see this as a big deal. :sigh:
-
den2k88 wrote:
What happened to the simple rule of checking for unexpected/invalid values before using them?
Now you're talking a religion of which I am a true believer ! So many questions on C# QA could be answered by the posters, themselves, if they had learned to check input values before calling them, and how to use a debugger. I am also in favor of disabling, or hiding, UI controls that are irrelevant to the current context, or which would create errors if clicked, or, which should only be used after specific action(s) by the user.
«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:
I am also in favor of disabling, or hiding, UI controls that are irrelevant to the current context, or which would create errors if clicked, or, which should only be used after specific action(s) by the user.
Absolutely. Even when I start not doing so I end up fixing it because during the tests I elephant up myself. The real problem is that noone programs anymore: now there are frameworks! Never release resources anymore, there is The Framework. Never think about what you have to do, The Framework has already a solution for you! If the solution is not right for your problem, modify the problem! Don't write your components: The Framework is better and there's no discussion on it! The Framework weights several hundred megabytes, has its own version of DLL hell which is not called Dll hell, can cease backwards compatibility every moment and lose its support or be replaced by The Next Framework, which is better! And incompatible. And so on so forth...
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver When I was six, there were no ones and zeroes - only zeroes. And not all of them worked. -- Ravi Bhavnani
-
Sander Rossel wrote:
.NET (and I guess IEEE) represents 1 / 0 as Infinity
No, it does not, where on earth did you get this idea from? How exactly do you represent infinity as a number in a computer?
I got it from simply running the following code in C#... :~
double a = 1;
double b = 0;
double c = a / b; // c is now double.InfinityI'm seeing the result is Infinity right here on my screen and you telling me it isn't and never was :confused:
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
-
You need to check for NaN before passing to min/max and eventually root out them by code. What happened to the simple rule of checking for unexpected/invalid values before using them? Does everybody now cross the streets without looking, eventually launching an exception if hit by a car?
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver When I was six, there were no ones and zeroes - only zeroes. And not all of them worked. -- Ravi Bhavnani
I'm writing the function that will be called by users that didn't check their input. At least I should know how to handle their crap :)
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 got it from simply running the following code in C#... :~
double a = 1;
double b = 0;
double c = a / b; // c is now double.InfinityI'm seeing the result is Infinity right here on my screen and you telling me it isn't and never was :confused:
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
-
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
1/0 is NOT infinity! I know you've already stated you're weak at maths, but try to do some basic research before posting non sense like that! 1/x with x -> 0 that is something completely different though! X| OK, I know I'm arguing with an idiot who actually thinks infinity is a number!
"I had the right to remain silent, but I didn't have the ability!"
Ron White, Comedian