Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. What the NaN?

What the NaN?

Scheduled Pinned Locked Moved The Lounge
csharpcomquestion
66 Posts 18 Posters 13 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Sander RosselS Sander Rossel

    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

    B Offline
    B Offline
    BillWoodruff
    wrote on last edited by
    #29

    Sander Rossel wrote:

    NaN will behave differently, feels very random.

    Sander, this is a brilliant idea you've come up with; I'll offer a quick sketch, and look forward to your comprehensive implementation:

    namespace CatState
    {
    public static class CatStateExtensions
    {
    public static double CatDead(this double[] args)
    {
    if (args.Contains(double.NaN))
    {
    Random rnd = new Random((int) DateTime.Now.Ticks);

                return (rnd.Next(0,2) == 0)
                    ? double.PositiveInfinity
                    : double.NegativeInfinity;
            }
    
            return args.Min();
        }
    
        public static double CatAlive(this double\[\] args)
        {
            if (args.Contains(double.NaN))
            {
                Random rnd = new Random((int) DateTime.Now.Ticks);
    
                return (rnd.Next(0,2) == 1)
                    ? double.PositiveInfinity
                    : double.NegativeInfinity;
            }
    
            return args.Max();
        }
    }
    

    }

    The half-dead cats fighting over half-dead fish-heads have been keeping me up nights, lately.

    «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

    M 1 Reply Last reply
    0
    • Sander RosselS Sander Rossel

      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

      M Offline
      M Offline
      Mladen Jankovic
      wrote on last edited by
      #30

      Sander Rossel wrote:

      they destroyed our numeric system to support some edge cases

      Any representation of real numbers in computer memory will destroy 'numeric system' since you're trying to represent infinite set with finite amount of memory.

      Sander Rossel wrote:

      Luckily .NET offers some sensible numeric types with int, long and decimal :-D

      decimal comes with performance costs as it has no support in hardware so it might not be suitable as a replacement in fields that traditionally use floating point arithmetic. It is meant to be used for financial stuff since IEEE754 is not suitable for that purpose, so not everyone have to invent their own way of doing math.

      Sander Rossel wrote:

      0.1 + 0.2 equals 0.30000000000000004

      That's the problem with converting real numbers between different bases.

      GeoGame for Windows Phone | The Lounge Explained In 5 Minutes

      1 Reply Last reply
      0
      • B BillWoodruff

        Sander Rossel wrote:

        NaN will behave differently, feels very random.

        Sander, this is a brilliant idea you've come up with; I'll offer a quick sketch, and look forward to your comprehensive implementation:

        namespace CatState
        {
        public static class CatStateExtensions
        {
        public static double CatDead(this double[] args)
        {
        if (args.Contains(double.NaN))
        {
        Random rnd = new Random((int) DateTime.Now.Ticks);

                    return (rnd.Next(0,2) == 0)
                        ? double.PositiveInfinity
                        : double.NegativeInfinity;
                }
        
                return args.Min();
            }
        
            public static double CatAlive(this double\[\] args)
            {
                if (args.Contains(double.NaN))
                {
                    Random rnd = new Random((int) DateTime.Now.Ticks);
        
                    return (rnd.Next(0,2) == 1)
                        ? double.PositiveInfinity
                        : double.NegativeInfinity;
                }
        
                return args.Max();
            }
        }
        

        }

        The half-dead cats fighting over half-dead fish-heads have been keeping me up nights, lately.

        «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

        M Offline
        M Offline
        Mladen Jankovic
        wrote on last edited by
        #31

        BillWoodruff wrote:

        Random rnd = new Random((int) DateTime.Now.Ticks);

        Reseeding RNG each time you make a call with nothing more than current time as a source of randomness, that's just a disaster waiting to happen. Output of your methods would be easily predictable. Nobody want their Schrödinger's cat predictable :)

        GeoGame for Windows Phone | The Lounge Explained In 5 Minutes

        B 1 Reply Last reply
        0
        • Sander RosselS Sander Rossel

          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

          J Offline
          J Offline
          Jochen Arndt
          wrote on last edited by
          #32

          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).

          Sander RosselS 1 Reply Last reply
          0
          • M Mladen Jankovic

            BillWoodruff wrote:

            Random rnd = new Random((int) DateTime.Now.Ticks);

            Reseeding RNG each time you make a call with nothing more than current time as a source of randomness, that's just a disaster waiting to happen. Output of your methods would be easily predictable. Nobody want their Schrödinger's cat predictable :)

            GeoGame for Windows Phone | The Lounge Explained In 5 Minutes

            B Offline
            B Offline
            BillWoodruff
            wrote on last edited by
            #33

            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

            Sander RosselS 1 Reply Last reply
            0
            • S Super Lloyd

              Did you know that both 1 < double.NaN and 1 > double.NaN are false?! ;P

              A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!

              B Offline
              B Offline
              BillWoodruff
              wrote on last edited by
              #34

              I thought Julian Assange had called off his latest announcement of new WikiLeak content: [^]. Revelations like this, calling into question the entire structure of the way we view reality and the code tools we use to model it, is going to really shake things up. The thought of the vast infinite hordes that NaN could mobilize and unleash on Primes and NotPrimes and SubPrimes ... frightening. I'm going to start building my bunker, now.

              «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

              S 1 Reply Last reply
              0
              • B BillWoodruff

                I thought Julian Assange had called off his latest announcement of new WikiLeak content: [^]. Revelations like this, calling into question the entire structure of the way we view reality and the code tools we use to model it, is going to really shake things up. The thought of the vast infinite hordes that NaN could mobilize and unleash on Primes and NotPrimes and SubPrimes ... frightening. I'm going to start building my bunker, now.

                «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

                S Offline
                S Offline
                Super Lloyd
                wrote on last edited by
                #35

                Doom is upon us! Or will be anytime soon now! :omg:

                A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!

                1 Reply Last reply
                0
                • Sander RosselS Sander Rossel

                  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

                  F Offline
                  F Offline
                  Florian Rappl
                  wrote on last edited by
                  #36

                  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.

                  1 Reply Last reply
                  0
                  • B BillWoodruff

                    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

                    Sander RosselS Offline
                    Sander RosselS Offline
                    Sander Rossel
                    wrote on last edited by
                    #37

                    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

                    1 Reply Last reply
                    0
                    • J Jochen Arndt

                      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).

                      Sander RosselS Offline
                      Sander RosselS Offline
                      Sander Rossel
                      wrote on last edited by
                      #38

                      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

                      J 1 Reply Last reply
                      0
                      • S Super Lloyd

                        Did you know that both 1 < double.NaN and 1 > double.NaN are false?! ;P

                        A new .NET Serializer All in one Menu-Ribbon Bar Taking over the world since 1371!

                        Sander RosselS Offline
                        Sander RosselS Offline
                        Sander Rossel
                        wrote on last edited by
                        #39

                        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

                        1 Reply Last reply
                        0
                        • L Lost User

                          NaN means Not a Number, so you cannot compare it to a proper number and get a valid response.

                          D Offline
                          D Offline
                          den2k88
                          wrote on last edited by
                          #40

                          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

                          1 Reply Last reply
                          0
                          • Sander RosselS Sander Rossel

                            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; // false

                            So 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

                            D Offline
                            D Offline
                            den2k88
                            wrote on last edited by
                            #41

                            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

                            B Sander RosselS 2 Replies Last reply
                            0
                            • Sander RosselS Sander Rossel

                              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

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #42

                              Sander Rossel wrote:

                              Yes you can, and that's the point.

                              Then be prepared to accept the consequences.

                              1 Reply Last reply
                              0
                              • Sander RosselS Sander Rossel

                                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

                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #43

                                Sander Rossel wrote:

                                And apparently 1/0 equals infinity.

                                No, it does not, and never has.

                                Sander RosselS 1 Reply Last reply
                                0
                                • L Lost User

                                  Sander Rossel wrote:

                                  And apparently 1/0 equals infinity.

                                  No, it does not, and never has.

                                  Sander RosselS Offline
                                  Sander RosselS Offline
                                  Sander Rossel
                                  wrote on last edited by
                                  #44

                                  double x = 1;
                                  double y = 0;
                                  double z = x / y; // Infinity

                                  Yes 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

                                  L 1 Reply Last reply
                                  0
                                  • Sander RosselS Sander Rossel

                                    double x = 1;
                                    double y = 0;
                                    double z = x / y; // Infinity

                                    Yes 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

                                    L Offline
                                    L Offline
                                    Lost User
                                    wrote on last edited by
                                    #45

                                    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.

                                    Sander RosselS 1 Reply Last reply
                                    0
                                    • L Lost User

                                      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.

                                      Sander RosselS Offline
                                      Sander RosselS Offline
                                      Sander Rossel
                                      wrote on last edited by
                                      #46

                                      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

                                      L 1 Reply Last reply
                                      0
                                      • Sander RosselS Sander Rossel

                                        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

                                        J Offline
                                        J Offline
                                        Jochen Arndt
                                        wrote on last edited by
                                        #47

                                        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).

                                        1 Reply Last reply
                                        0
                                        • Sander RosselS Sander Rossel

                                          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

                                          L Offline
                                          L Offline
                                          Lost User
                                          wrote on last edited by
                                          #48

                                          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?

                                          Sander RosselS F 2 Replies Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups