Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Comparing doubles properly
Forum Updated to NodeBB v4.3 + New Features

Comparing doubles properly

Scheduled Pinned Locked Moved C++ Gurus
7 Posts 6 Posters 27.5k 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.
  • J Offline
    J Offline
    Jupiter
    wrote on last edited by
    #1

    Hi,

    i have a problem with a piece of code:

    @qreal a = 0.0f;
    Q_ASSERT(qAbs(a) == 0)@

    this causes sometimes to throw the assert, and sometimes not. but why? in my real there is a value like 6.0*10^-311 so its almost 0 but it is not 0, so the assert is right. but why isn't it 0 when i initialized it with 0?

    1 Reply Last reply
    0
    • L Offline
      L Offline
      lgeyer
      wrote on last edited by
      #2

      This is due to limited precision of floating point numbers. Use "qFuzzyCompare()":http://doc.qt.nokia.com/4.7-snapshot/qtglobal.html#qFuzzyCompare-2 instead.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        Jupiter
        wrote on last edited by
        #3

        thanks.

        I also found the method qFuzzyIsNull() its not in the doc, but compares the parameter with 0.0 thats exactly what i need

        1 Reply Last reply
        0
        • A Offline
          A Offline
          ardhitama
          wrote on last edited by
          #4

          @qreal a = 0.0f;
          Q_ASSERT(qAbs(a) < 1e-8 && qAbs(a) > 0.0f)@

          Comparing to real number to zero is almost not possible in reality, but if you dare, you could also try this:

          @qreal a = 0.0f;
          Q_ASSERT(qAbs(a) == 0.0f)@

          Love automagically stuffs

          1 Reply Last reply
          0
          • G Offline
            G Offline
            goetz
            wrote on last edited by
            #5

            [quote author="Jupiter" date="1319709690"]thanks.

            I also found the method qFuzzyIsNull() its not in the doc, but compares the parameter with 0.0 thats exactly what i need[/quote]

            qFuzzyIsNull is declared internal in the sources. Usually that's for a reason...

            You might want to open a request to make it officially public in the "bug tracker":https://bugreports.qt.nokia.com though.

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Al79
              wrote on last edited by
              #6

              I guess this is the reason:

              "Donald Knuth a famous computer scientist, suggested the following method in his book “The Art of Computer Programming, Volume II: Seminumerical Algorithms (Addison-Wesley, 1969)”:
              @
              bool IsEqual(double dX, double dY)
              {
              const double dEpsilon = 0.000001; // or some other small number
              return fabs(dX - dY) <= dEpsilon * fabs(dX);
              }
              @
              dEpsilon is a very small value (eg. 0.000001) that is used to help define what “close enough” is. fabs() is a function in the standard library (#include <cmath>) that returns the absolute value of it’s double parameter.[...]"

              "look at this link for more details":http://www.learncpp.com/cpp-tutorial/35-relational-operators-comparisons/

              You surely just solved, but maybe it could be useful for someone else....

              1 Reply Last reply
              0
              • A Offline
                A Offline
                Asperamanca
                wrote on last edited by
                #7

                The epsilon method is useful, but with a fixed epsilon, it will only work properly for a certain range of values.

                This is why qFuzzyCompare uses a variable epsilon, depending on the values compared. However, when getting very close to zero, the epsilon becomes zero as well, and it's no longer a fuzzyCompare.

                I solved this by writing a wrapper that checks whether both compared values are very close to zero, then add a fixed amount (e.g. 1.0) to both of them. That way, the qFuzzyCompare I call internally never sees values that are close to zero, and works.

                One word of warning: When using a fuzzy compare, expect that a value can both be equal and greater/lesser.
                For example, when you first have

                @if (fuzzyIsEqual(a, b)@

                but later realize that all you need is a > b, you might think that you no longer need a fuzzyCompare. Of course you can replace the code with

                @if (a > b)@

                but this will not trigger in cases when the previous code did, and might cause unexpected results.

                Better, in this case to do a
                @if (fuzzyIsGreaterOrEqual(a, b)@

                (which of course you have to write yourself first)

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved