double compare 0.2 != 0.2 How?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Bassem
    Contributor
    • Dec 2008
    • 344

    double compare 0.2 != 0.2 How?

    I'm working on a real-time reservation graph. And it keeps giving me error even I tested each Method and each statement except this one, which I did this early morning.
    What suppose these statements do?
    Code:
    MessageBox.Show(Convert.ToString((1.0 - 0.8) == 0.2));
    I felt wrong about anything I didn't see, I tested this too
    Code:
    MessageBox.Show(Convert.ToString(((double)(1.0 - 0.8)).CompareTo(0.2)));
    I waited for True from each, but both give false!!!

    Help!!!!!!!!!!! !!
    Please any help!!!!!!!!!
  • artov
    New Member
    • Jul 2008
    • 40

    #2
    Because 0.2 cannot be represented exact on floating point, value readed by the compiler and calculated from two double numbers (where 0.8 cannot also be repsesented exact), there has to be some differences.

    For online help, check http://www.h-schmidt.net/FloatApplet/IEEE754.html or read wikipedia.

    Comment

    • Plater
      Recognized Expert Expert
      • Apr 2007
      • 7872

      #3
      What error are you getting?
      EDIT: NM I see

      Comment

      • Bassem
        Contributor
        • Dec 2008
        • 344

        #4
        Great I know the representation of a floating-point number. But What should I do?!
        I'm comparing two double numbers and get wrong result.
        Any idea. I can't step back for that, my application depends on that comparison.

        Comment

        • Plater
          Recognized Expert Expert
          • Apr 2007
          • 7872

          #5
          Outside the box time.

          Consider this:
          [code=c#]
          double a = 1.0;
          double b = 0.8;
          double c = 0.2;
          MessageBox.Show ("" + ((a - b) + (a - c) == a));
          [/code]
          The result is true. Perhaps you can work out the routine to do this to fit your needs?

          Comment

          • Bassem
            Contributor
            • Dec 2008
            • 344

            #6
            Hello Plater,
            I'm so sorry for wasting your time with such a question. Thanks for replying.
            I tested your code and the result is True, as it should of course.
            Could you please test mine, it also should give True, but I swear with VS2005 that it gives me False.
            Code:
                        double a = 1.0;
                        double b = 0.2;
                        double c = 0.8;
            
                        MessageBox.Show("" + ((1.0 - 0.8) == 0.2));
            I fell stupid to ask you this, please copy and test it.
            Tell me why it gives False!
            Again I've to say sorry for wasting your time.

            Regards,
            Bassem

            Comment

            • Plater
              Recognized Expert Expert
              • Apr 2007
              • 7872

              #7
              No no, you are correct, yours will give false.
              I speculate that since one side is a specified value and the other is computed they are treated differently.
              That is why I was saying use my code, they are functionaly identical mathmatically.

              If yours was a function like this:
              [code=c#]
              bool TestDouble(doub le a, double b, double c)
              {
              return ((a - b) == c);
              //could also write it ((2*a - b - c)==a)
              }
              [/code]
              You would call it with:
              MessageBox.Show (TestDouble(1.0 ,0.8,0.2).ToStr ing());

              But as you said, you will get "False" instead of the expected "True"

              So if you instead used my function:
              [code=c#]
              bool TestDouble(doub le a, double b, double c)
              {
              return ((a - b) + (a - c) == a));
              }
              [/code]
              You could again call it with:
              MessageBox.Show (TestDouble(1.0 ,0.8,0.2).ToStr ing());

              Only now you would get the expected "True"

              Comment

              • Bassem
                Contributor
                • Dec 2008
                • 344

                #8
                This is the most strange thing I ever seen in C#, Can you please give me a reference to read more. I didn't understand yet the difference.

                Comment

                • Curtis Rutland
                  Recognized Expert Specialist
                  • Apr 2008
                  • 3264

                  #9
                  This is an interesting topic. I'm just commenting to subscribe and remind me to look at it later.

                  Comment

                  • IanWright83
                    New Member
                    • Apr 2009
                    • 9

                    #10
                    Sorry I didn't reply earlier. Account has been locked out and only just figured out how to create a new account with my existing email address.

                    Anyway, what you need to look at is Math.Round(). I believe if you do the following you'll get your answer.

                    Code:
                    MessageBox.Show(Math.Round(1.0 - 0.8, 1) == 0.2));

                    Comment

                    • Curtis Rutland
                      Recognized Expert Specialist
                      • Apr 2008
                      • 3264

                      #11
                      I'm actually interested in the "why" of this problem. Why does a computed value differ from a literal in this case.

                      Comment

                      • IanWright83
                        New Member
                        • Apr 2009
                        • 9

                        #12
                        Originally posted by insertAlias
                        I'm actually interested in the "why" of this problem. Why does a computed value differ from a literal in this case.
                        Quite simply because it is floating point arithmetic. It's a well known common problem.

                        Comment

                        • r035198x
                          MVP
                          • Sep 2006
                          • 13225

                          #13
                          The morale of the story is that never (ever) use == (or !=) for comparing floating point numbers. There are numbers that the computer cannot represent in binary exactly simply because they are recurring numbers. For those numbers, the exact value stored is dependent on the platform being used and the precision possible on those platforms.
                          e.g
                          (Requesting your forgiveness for polluting your esteemed forum with the dreadful Java codes)
                          Code:
                          System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
                          does not print 1.0 on my computer.

                          Here is What every computer scientist should know about floating point arithmetic

                          Comment

                          • IanWright83
                            New Member
                            • Apr 2009
                            • 9

                            #14
                            I'm kinda amazed that the other moderator/forum leaders didn't know this actually... You can't get very far with doubles without knowing about the rounding issues.

                            Comment

                            • r035198x
                              MVP
                              • Sep 2006
                              • 13225

                              #15
                              I'm not too amazed. The forum administrative roles do not reflect on how much someone knows about subjects. They do know some pretty amazing things though which I don't know too. That's what makes forums amazing. Everyone gets to learn.

                              Comment

                              Working...