Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QString::number doesn't round
Forum Updated to NodeBB v4.3 + New Features

QString::number doesn't round

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 2.7k 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Hello,

    I have this code: QString::number(dTotal * 1.19, 'f', 2)

    dTotal has a value of 198.135 but it still prints out 198.13 for me and I don't understand why. All other values for example dTotal * 0.19 will be 31.635 which he prints correctly as 31.64

    Full code:

    painter.drawText(g_preis7, Qt::AlignRight, ""+QString::number(dTotal * 0.19, 'f', 2)+"");
    painter.drawText(g_preis8, Qt::AlignRight, ""+QString::number(dTotal * 1.19, 'f', 2)+"");
    
    JonBJ JKSHJ 2 Replies Last reply
    0
    • ? A Former User

      Hello,

      I have this code: QString::number(dTotal * 1.19, 'f', 2)

      dTotal has a value of 198.135 but it still prints out 198.13 for me and I don't understand why. All other values for example dTotal * 0.19 will be 31.635 which he prints correctly as 31.64

      Full code:

      painter.drawText(g_preis7, Qt::AlignRight, ""+QString::number(dTotal * 0.19, 'f', 2)+"");
      painter.drawText(g_preis8, Qt::AlignRight, ""+QString::number(dTotal * 1.19, 'f', 2)+"");
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @portstone

      198.135 but it still prints out 198.13

      31.635 which he prints correctly as 31.64

      By what "rounding criteria" are you claiming/assuming the first is incorrect but the second is correct?

      Some example discussions of this behaviour are:

      • https://stackoverflow.com/questions/24120888/why-printf-round-floating-point-numbers
      • https://stackoverflow.com/questions/10357192/printf-rounding-behavior-for-doubles
      • https://www.reddit.com/r/perl/comments/80p0rq/printf_rounding_inconsistencies_at_4_decimal/
      • https://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/

      You need to use a math-type library call if you want more precise control over rounding behaviour.

      ? 1 Reply Last reply
      1
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by Christian Ehrlicher
        #3

        I simply quote Thiago from https://bugreports.qt.io/browse/QTBUG-4280

        Not a bug - 'printf("%.2f", 166.5 * 1.19);' also prints 198.13

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        3
        • JonBJ JonB

          @portstone

          198.135 but it still prints out 198.13

          31.635 which he prints correctly as 31.64

          By what "rounding criteria" are you claiming/assuming the first is incorrect but the second is correct?

          Some example discussions of this behaviour are:

          • https://stackoverflow.com/questions/24120888/why-printf-round-floating-point-numbers
          • https://stackoverflow.com/questions/10357192/printf-rounding-behavior-for-doubles
          • https://www.reddit.com/r/perl/comments/80p0rq/printf_rounding_inconsistencies_at_4_decimal/
          • https://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/

          You need to use a math-type library call if you want more precise control over rounding behaviour.

          ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          @jonb because at 5, 6, 7, 8, 9 you round up and that is why it is for me incorrect. But I didn't knew that compilers are handling it with different methods / rules.

          1 Reply Last reply
          0
          • ? A Former User

            Hello,

            I have this code: QString::number(dTotal * 1.19, 'f', 2)

            dTotal has a value of 198.135 but it still prints out 198.13 for me and I don't understand why. All other values for example dTotal * 0.19 will be 31.635 which he prints correctly as 31.64

            Full code:

            painter.drawText(g_preis7, Qt::AlignRight, ""+QString::number(dTotal * 0.19, 'f', 2)+"");
            painter.drawText(g_preis8, Qt::AlignRight, ""+QString::number(dTotal * 1.19, 'f', 2)+"");
            
            JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by JKSH
            #5

            The issue here is not related to the links posted above. In those links, the numbers being discussed have exact representations in IEEE-754. However, 198.135 and 31.635 don't fall in this category.

            @portstone said in QString::number doesn't round:

            dTotal has a value of 198.135 but it still prints out 198.13

            It is impossible to store 198.135 in IEEE-754. Your actual value is:

            • float: 198.1349945068359375
            • double: 198.134999999999990905052982270717620849609375

            And I expect all compilers to round 198.13499... to 198.13.

            All other values for example dTotal * 0.19 will be 31.635 which he prints correctly as 31.64

            It is also impossible to store 31.635 in IEEE-754. Your actual value is:

            • float: 31.6350002288818359375
            • double: 31.635000000000001563194018672220408916473388671875

            And I expect all compilers to round 31.63500... to 31.64.

            I don't understand why.

            First, experiment with this tool: https://www.h-schmidt.net/FloatConverter/IEEE754.html

            Then, read http://blog.reverberate.org/2014/09/what-every-computer-programmer-should.html

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            JonBJ 1 Reply Last reply
            6
            • JKSHJ JKSH

              The issue here is not related to the links posted above. In those links, the numbers being discussed have exact representations in IEEE-754. However, 198.135 and 31.635 don't fall in this category.

              @portstone said in QString::number doesn't round:

              dTotal has a value of 198.135 but it still prints out 198.13

              It is impossible to store 198.135 in IEEE-754. Your actual value is:

              • float: 198.1349945068359375
              • double: 198.134999999999990905052982270717620849609375

              And I expect all compilers to round 198.13499... to 198.13.

              All other values for example dTotal * 0.19 will be 31.635 which he prints correctly as 31.64

              It is also impossible to store 31.635 in IEEE-754. Your actual value is:

              • float: 31.6350002288818359375
              • double: 31.635000000000001563194018672220408916473388671875

              And I expect all compilers to round 31.63500... to 31.64.

              I don't understand why.

              First, experiment with this tool: https://www.h-schmidt.net/FloatConverter/IEEE754.html

              Then, read http://blog.reverberate.org/2014/09/what-every-computer-programmer-should.html

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @jksh
              At first in my reply I wrote about maybe the numbers OP was using did not have the representation he expected when as a float/double. Then I thought I had no evidence for that so I scrubbed that part. Looks like I should have stuck with it!

              I did not know there was a tool like you mention which allows to easily examine what the representation is. How did you know other numbers do have "exact" representation while the numbers the OP mentions do not? I have typed some random (floating) numbers into the tool and as far as I can see none of them have an exact. For x.yz5 they all vary between like x.yz499... and x.yz501.... So I would sort of expect the 0.005 at the end of such numbers to round as 0.00499 half of the time and 0.00501 the other half, i.e. half the time round down, half the time round up. Is that right?

              Second question: let's say I want to round my numbers to even, e.g. 1.235 -> 1.24, 1.285 -> 1.28. There are libraries to do that. But that seems to me to rely on the number with the trailing 0.005 starting out with exactly that representation, because the rounding to even only applies to numbers ending in 5. How does that work if much of the time you cannot even get an accurate representation which really does end in a 5, if it's always ....4999... or ...5001... then the even rounding won't be invoked?

              JKSHJ 1 Reply Last reply
              0
              • JonBJ JonB

                @jksh
                At first in my reply I wrote about maybe the numbers OP was using did not have the representation he expected when as a float/double. Then I thought I had no evidence for that so I scrubbed that part. Looks like I should have stuck with it!

                I did not know there was a tool like you mention which allows to easily examine what the representation is. How did you know other numbers do have "exact" representation while the numbers the OP mentions do not? I have typed some random (floating) numbers into the tool and as far as I can see none of them have an exact. For x.yz5 they all vary between like x.yz499... and x.yz501.... So I would sort of expect the 0.005 at the end of such numbers to round as 0.00499 half of the time and 0.00501 the other half, i.e. half the time round down, half the time round up. Is that right?

                Second question: let's say I want to round my numbers to even, e.g. 1.235 -> 1.24, 1.285 -> 1.28. There are libraries to do that. But that seems to me to rely on the number with the trailing 0.005 starting out with exactly that representation, because the rounding to even only applies to numbers ending in 5. How does that work if much of the time you cannot even get an accurate representation which really does end in a 5, if it's always ....4999... or ...5001... then the even rounding won't be invoked?

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                @jonb said in QString::number doesn't round:

                How did you know other numbers do have "exact" representation while the numbers the OP mentions do not?

                I opened the links that you and @Christian-Ehrlicher posted, found the test numbers, and plugged those numbers into https://www.h-schmidt.net/FloatConverter/IEEE754.html. Then, I did the same with the OP's numbers :)

                I have typed some random (floating) numbers into the tool and as far as I can see none of them have an exact. For x.yz5 they all vary between like x.yz499... and x.yz501....

                There are infinitely more real numbers that have no exact representation in IEE-754, compared to real numbers that do have exact representations. So statistically, a randomly-chosen number has a negligible chance of being exactly representable as a float/double.

                To easily find a number with an exact representation, divide 2 by an integer. 2, 1, 0.5, 0.25, 0.125, 0.0625, 0.03125, ... have exact representations.

                So I would sort of expect the 0.005 at the end of such numbers to round as 0.00499 half of the time and 0.00501 the other half, i.e. half the time round down, half the time round up. Is that right?

                My gut feeling agrees with you, but I don't have any proof at the moment.

                Second question: let's say I want to round my numbers to even, e.g. 1.235 -> 1.24, 1.285 -> 1.28. There are libraries to do that. But that seems to me to rely on the number with the trailing 0.005 starting out with exactly that representation, because the rounding to even only applies to numbers ending in 5. How does that work if much of the time you cannot even get an accurate representation which really does end in a 5, if it's always ....4999... or ...5001... then the even rounding won't be invoked?

                I've never tried it myself, but there are publicly available implementations: https://stackoverflow.com/questions/32246103/rounding-doubles-to-n-decimal-points-using-round-to-even-in-c

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                JonBJ 1 Reply Last reply
                3
                • JKSHJ JKSH

                  @jonb said in QString::number doesn't round:

                  How did you know other numbers do have "exact" representation while the numbers the OP mentions do not?

                  I opened the links that you and @Christian-Ehrlicher posted, found the test numbers, and plugged those numbers into https://www.h-schmidt.net/FloatConverter/IEEE754.html. Then, I did the same with the OP's numbers :)

                  I have typed some random (floating) numbers into the tool and as far as I can see none of them have an exact. For x.yz5 they all vary between like x.yz499... and x.yz501....

                  There are infinitely more real numbers that have no exact representation in IEE-754, compared to real numbers that do have exact representations. So statistically, a randomly-chosen number has a negligible chance of being exactly representable as a float/double.

                  To easily find a number with an exact representation, divide 2 by an integer. 2, 1, 0.5, 0.25, 0.125, 0.0625, 0.03125, ... have exact representations.

                  So I would sort of expect the 0.005 at the end of such numbers to round as 0.00499 half of the time and 0.00501 the other half, i.e. half the time round down, half the time round up. Is that right?

                  My gut feeling agrees with you, but I don't have any proof at the moment.

                  Second question: let's say I want to round my numbers to even, e.g. 1.235 -> 1.24, 1.285 -> 1.28. There are libraries to do that. But that seems to me to rely on the number with the trailing 0.005 starting out with exactly that representation, because the rounding to even only applies to numbers ending in 5. How does that work if much of the time you cannot even get an accurate representation which really does end in a 5, if it's always ....4999... or ...5001... then the even rounding won't be invoked?

                  I've never tried it myself, but there are publicly available implementations: https://stackoverflow.com/questions/32246103/rounding-doubles-to-n-decimal-points-using-round-to-even-in-c

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @jksh said in QString::number doesn't round:

                  There are infinitely more real numbers that have no exact representation in IEE-754, compared to real numbers that do have exact representations. So statistically, a randomly-chosen number has a negligible chance of being exactly representable as a float/double.

                  Yes, that is indeed a good point! And someone who actually knows to use the word "infinite" correctly :)

                  To easily find a number with an exact representation, divide 2 by an integer. 2, 1, 0.5, 0.25, 0.125, 0.0625, 0.03125, ... have exact representations.

                  I regard that as cheating! Clearly I did not intend to ask about floats reached by dividing integers by 2, which even my cat understands are representable in IEEE ;-)

                  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