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. [SOLVED] Double to Int
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Double to Int

Scheduled Pinned Locked Moved C++ Gurus
16 Posts 6 Posters 39.4k 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.
  • D Offline
    D Offline
    david.luggen
    wrote on last edited by
    #1

    Hello

    If I try to cast a double with one decimal place to an int like this,

    @intVariable = (int)(doubleVariable100);@ or
    @intVariable = static_cast<int>(doubleVariable
    100);@

    I get from time to time an error with the cast. E.g. if I want to cast the double 4.2 into the int 420, I get 419 with this method. One solution would be to add 0.001 to every double, but I think this isn't really proper. Is there some other possibility to avoid this error.

    Thx for help.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      cincirin
      wrote on last edited by
      #2

      try this: @intVariable = static_cast<int>(doubleVariable + .5f) * 100@
      In other words (int)1.1f = 1 and (int)1.9f = 1
      http://www.cs.tut.fi/~jkorpela/round.html

      1 Reply Last reply
      0
      • JohanSoloJ Offline
        JohanSoloJ Offline
        JohanSolo
        wrote on last edited by
        #3

        [quote author="cincirin" date="1306928926"]try this: @intVariable = static_cast<int>(doubleVariable + .5f) * 100@
        In other words (int)1.1f = 1 and (int)1.9f = 1[/quote]

        I think this piece of code will give you 400 with an input value of 4.2... The multiplication has to be inside the static_cast as well. I'd rather try :

        @intVariable = static_cast<int>(doubleVariable * 100. + .5) @

        Note that I also changed .5f into .5, since doubleVariable is (I think) a double and not a float.

        `They did not know it was impossible, so they did it.'
        -- Mark Twain

        1 Reply Last reply
        0
        • D Offline
          D Offline
          david.luggen
          wrote on last edited by
          #4

          As Johan Solo said:

          4.2 -> int = 4 *100 = 400;

          Correctly arranged it comes to this:

          @intVariable = static_cast<int>(doubleVariable *100 + .5)@

          That looks like the same solution as to add 0.001. The question is why does it cast a double like 420.0 to the int 419? And how can this cast error else be resolved instead of adding half or a bit of an int?

          1 Reply Last reply
          0
          • K Offline
            K Offline
            koahnig
            wrote on last edited by
            #5

            The problem is because of floating point representation in any programming language. The conversion from double to int is just truncating without rounding.

            Vote the answer(s) that helped you to solve your issue(s)

            1 Reply Last reply
            0
            • JohanSoloJ Offline
              JohanSoloJ Offline
              JohanSolo
              wrote on last edited by
              #6

              [quote author="luggi" date="1306929905"]That looks like the same solution as to add 0.001. The question is why does it cast a double like 420 to the int 419? And how can this cast error else be resolved instead of adding half or a bit of an int?[/quote]

              It's a bit more clever that just adding .001, it ensures that the rounding will be done properly. When you cast a double / float value into a integer, no rounding is performed, the biggest integer value smaller than your floating point value is returned (the "floor function":http://www.cplusplus.com/reference/clibrary/cmath/floor/). Another complication is that some numbers don't have an exact representation on a float / double. For instance 0.1 is 0.00011001100110011… (see "here":http://www.learncpp.com/cpp-tutorial/25-floating-point-numbers/).

              `They did not know it was impossible, so they did it.'
              -- Mark Twain

              1 Reply Last reply
              0
              • D Offline
                D Offline
                david.luggen
                wrote on last edited by
                #7

                Okay thx. So finally I can assume that to add 0.5 is the best method to solve this problem.

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  koahnig
                  wrote on last edited by
                  #8

                  [quote author="luggi" date="1306930544"]Okay thx. So finally I can assume that to add 0.5 is the best method to solve this problem.[/quote]

                  You might want to be careful. Just adding 0.5 is not always the solution. For negative numbers you run into the opposite problem.
                  A typical solution for rounding is:
                  @
                  inline double nint (double x)
                  {
                  return x < 0 ? ceil (x - 0.5) : floor (x + 0.5);
                  }
                  @

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    david.luggen
                    wrote on last edited by
                    #9

                    Isn't there any method in Qt that does exactly this? I use this quiet a lot and it would be useful if I can apply it directly to the double.

                    1 Reply Last reply
                    0
                    • JohanSoloJ Offline
                      JohanSoloJ Offline
                      JohanSolo
                      wrote on last edited by
                      #10

                      I cannot tell whether such a function exists in Qt, but I think you should just define a function which uses koahnig's code, maybe you want the function to return an int directly.

                      `They did not know it was impossible, so they did it.'
                      -- Mark Twain

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        koahnig
                        wrote on last edited by
                        #11

                        Not to my knowledge. I guess a lot of programmers are using the line directly or have it somewhere in there headers. Rounding is nothing Qt specific. It is more basic programming in any programming language.

                        Vote the answer(s) that helped you to solve your issue(s)

                        1 Reply Last reply
                        0
                        • Z Offline
                          Z Offline
                          ZapB
                          wrote on last edited by
                          #12

                          Look at qRound() and qRound64() in qglobal.h.

                          Nokia Certified Qt Specialist
                          Interested in hearing about Qt related work

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            david.luggen
                            wrote on last edited by
                            #13

                            That's it, thx!

                            1 Reply Last reply
                            0
                            • T Offline
                              T Offline
                              tanquist
                              wrote on last edited by
                              #14

                              I don't think the (int) type conversion behavior was adequately explained. I ran into a similar problem converting an old C++ project into Qt.
                              The original code also had an equation similar to
                              @intVariable = (int)(doubleVariable*100);@

                              This worked as expected in my old project: it truncated doubleVariable*100 to a whole number without changing the value in the ones place. That is also what all of the documentation I've read says it will do.
                              However, in my Qt project the behavior varies depending on the value of doubleVariable (see below). I don't understand why it thinks 1.55 * 100 = 155 but 2.55 * 100 < 255. I can do a workaround usng qRound but I don't get why a formerly reliable type conversion is no longer so. Can anyone help me understand this?

                              <table>
                              <tr>
                              <td>doubleVariable</td>
                              <td>integerVariable</td>
                              </tr>
                              <tr>
                              <td>0.55</td>
                              <td>55</td>
                              </tr>
                              <tr>
                              <td>1.55</td>
                              <td>155</td>
                              </tr>
                              <tr>
                              <td>2.55</td>
                              <td>254</td>
                              </tr>
                              <tr>
                              <td>3.55</td>
                              <td>354</td>
                              </tr>
                              <tr>
                              <td>4.55</td>
                              <td>454</td>
                              </tr>
                              <tr>
                              <td>5.55</td>
                              <td>554</td>
                              </tr>
                              <tr>
                              <td>6.55</td>
                              <td>654</td>
                              </tr>
                              <tr>
                              <td>7.55</td>
                              <td>754</td>
                              </tr>
                              <tr>
                              <td>8.55</td>
                              <td>855</td>
                              </tr>
                              <tr>
                              <td>9.55</td>
                              <td>955</td>
                              </tr>
                              </table>

                              1 Reply Last reply
                              0
                              • D Offline
                                D Offline
                                david.luggen
                                wrote on last edited by
                                #15

                                Hey tanquist

                                The explanation why it happens is how a double is stored. E.g. the value 1.55 is not possible to be represented by a double. Therefore, if you write it into a double, the value is rounded to the next possible double value, which is 1.55000000000000004440892098501. Multiplied by 100 resolves in 155.000000000000004440892098501 stored in a double will be 155. That casted to an integer yields 155, which is expected.

                                But 2.55 will be rounded to the next double value 2.54999999999999982236431605997. Multiplied by 100 is 254.999999999999982236431605997 stored in a double will be 254.999999999999971578290569596. That casted to an integer results in 254. That is the experienced behaviour and the reason why rounding should be used.

                                I tested your numbers also in a float format. At this point every number converts to the expected value because the representation is different.

                                Maybe your old project used 32-bit for double values, this could be one explanation or you used float variables.

                                Nevertheless, the fact that exact these values converted right is coincidence in my opinion and rounding should always be necessary.

                                By the way, this script converts decimals to binaries and shows their "real" value if floating point is used: "BinaryConvert":http://www.binaryconvert.com/convert_double.html ( October 2014 ).

                                1 Reply Last reply
                                0
                                • T Offline
                                  T Offline
                                  tanquist
                                  wrote on last edited by
                                  #16

                                  Thank you luggi for that excellent explanation and the conversion resource. This understanding makes the problem much less frustrating.

                                  I've replaced all of my (int) and (long) conversions with variations on the function koahnig provided:

                                  @int nint(double x) // provided by koahnig at qt-project.org
                                  {// avoids binary rounding error in (int) conversion
                                  return x < 0 ? (int)ceil(x) : (int)floor(x);
                                  }@

                                  @long nlong(double x)
                                  {// avoids binary rounding error in (long) conversion
                                  return x < 0 ? (long)ceil(x) : (long)floor(x);
                                  }@

                                  If anyone sees problems with my method please let me know.

                                  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