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. Float and QString: Strange problem
Qt 6.11 is out! See what's new in the release blog

Float and QString: Strange problem

Scheduled Pinned Locked Moved Unsolved General and Desktop
28 Posts 7 Posters 6.3k Views 2 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.
  • M Offline
    M Offline
    Marce
    wrote on last edited by
    #1

    I have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

    I have the following code.

    grade_lat = abs (Lat);
    grade_long = abs(Long);
    min_lat = 60*(abs (Lat) - grade_lat);
    min_long = 60*(abs (Long) - grade_long);
    
    if (min_long >= 60)
         {
          min_long -= 60;
          grade_long++;
         }
    
    if (min_lat >= 60)
         {
          min_lat -= 60;
          grade_lat++;
         }
    
    qDebug() << "long calculated: "+QString::number(Long,'f',7)+" grade_long: "+QString::number(grade_long,'f',7)+" min_long: "+QString::number(min_long,'f',7);
    
    qDebug() << "lat calculated: "+QString::number(Lat,'f',7)+" grade_lat: "+QString::number(grade_lat,'f',7)+" min_lat: "+QString::number(min_lat,'f',7);
    

    At one point the QDebug has written the following:

    "long calculated: -61.0000000 grade_long: 60.0000000 min_long: 60.0000000"
    "lat calculated: -31.0000000 grade_lat: 31.0000000 min_lat: 0.0000000"
    

    It is strange that 61 degrees are written as 60 degrees and 60 minutes and for 31 degrees work well.

    If I initialize the variables in 61.0f and 31.0f the QDebug writes well so I guess that in the variable of 61.0 degrees there are actually 60.9999999999999999999999 degrees but I need the Qdebug to write "61 degrees 0 minutes" or write "60 degrees 59.99999999999 minutes".

    How can I implement this without failing?

    Tanks

    Marcelo

    aha_1980A kshegunovK Pablo J. RoginaP 3 Replies Last reply
    0
    • M Marce

      I have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

      I have the following code.

      grade_lat = abs (Lat);
      grade_long = abs(Long);
      min_lat = 60*(abs (Lat) - grade_lat);
      min_long = 60*(abs (Long) - grade_long);
      
      if (min_long >= 60)
           {
            min_long -= 60;
            grade_long++;
           }
      
      if (min_lat >= 60)
           {
            min_lat -= 60;
            grade_lat++;
           }
      
      qDebug() << "long calculated: "+QString::number(Long,'f',7)+" grade_long: "+QString::number(grade_long,'f',7)+" min_long: "+QString::number(min_long,'f',7);
      
      qDebug() << "lat calculated: "+QString::number(Lat,'f',7)+" grade_lat: "+QString::number(grade_lat,'f',7)+" min_lat: "+QString::number(min_lat,'f',7);
      

      At one point the QDebug has written the following:

      "long calculated: -61.0000000 grade_long: 60.0000000 min_long: 60.0000000"
      "lat calculated: -31.0000000 grade_lat: 31.0000000 min_lat: 0.0000000"
      

      It is strange that 61 degrees are written as 60 degrees and 60 minutes and for 31 degrees work well.

      If I initialize the variables in 61.0f and 31.0f the QDebug writes well so I guess that in the variable of 61.0 degrees there are actually 60.9999999999999999999999 degrees but I need the Qdebug to write "61 degrees 0 minutes" or write "60 degrees 59.99999999999 minutes".

      How can I implement this without failing?

      Tanks

      Marcelo

      aha_1980A Offline
      aha_1980A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Marce

      Please update your code so it actually contains the data types of all involved variables.

      I guess you're converting a double to an int which would explain that truncation. I you really want to do it, then simply add 0.5 to the double before conversion. Otherwise calculate everything in double.

      Regards

      Qt has to stay free or it will die.

      M 1 Reply Last reply
      1
      • M Marce

        I have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

        I have the following code.

        grade_lat = abs (Lat);
        grade_long = abs(Long);
        min_lat = 60*(abs (Lat) - grade_lat);
        min_long = 60*(abs (Long) - grade_long);
        
        if (min_long >= 60)
             {
              min_long -= 60;
              grade_long++;
             }
        
        if (min_lat >= 60)
             {
              min_lat -= 60;
              grade_lat++;
             }
        
        qDebug() << "long calculated: "+QString::number(Long,'f',7)+" grade_long: "+QString::number(grade_long,'f',7)+" min_long: "+QString::number(min_long,'f',7);
        
        qDebug() << "lat calculated: "+QString::number(Lat,'f',7)+" grade_lat: "+QString::number(grade_lat,'f',7)+" min_lat: "+QString::number(min_lat,'f',7);
        

        At one point the QDebug has written the following:

        "long calculated: -61.0000000 grade_long: 60.0000000 min_long: 60.0000000"
        "lat calculated: -31.0000000 grade_lat: 31.0000000 min_lat: 0.0000000"
        

        It is strange that 61 degrees are written as 60 degrees and 60 minutes and for 31 degrees work well.

        If I initialize the variables in 61.0f and 31.0f the QDebug writes well so I guess that in the variable of 61.0 degrees there are actually 60.9999999999999999999999 degrees but I need the Qdebug to write "61 degrees 0 minutes" or write "60 degrees 59.99999999999 minutes".

        How can I implement this without failing?

        Tanks

        Marcelo

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #3
        double coordinate;
        
        int degrees = int(coordinate);
        coordinate = (coordinate - degrees) * 60;
        int minutes = int(coordinate);
        int seconds = (coordinate - minutes) * 60;
        

        PS.
        Usually the seconds are taken as a floating point, not as int as here.

        Read and abide by the Qt Code of Conduct

        M 1 Reply Last reply
        2
        • kshegunovK kshegunov
          double coordinate;
          
          int degrees = int(coordinate);
          coordinate = (coordinate - degrees) * 60;
          int minutes = int(coordinate);
          int seconds = (coordinate - minutes) * 60;
          

          PS.
          Usually the seconds are taken as a floating point, not as int as here.

          M Offline
          M Offline
          Marce
          wrote on last edited by
          #4

          @kshegunov I use grade (int) and minutes (double) only.

          1 Reply Last reply
          0
          • aha_1980A aha_1980

            @Marce

            Please update your code so it actually contains the data types of all involved variables.

            I guess you're converting a double to an int which would explain that truncation. I you really want to do it, then simply add 0.5 to the double before conversion. Otherwise calculate everything in double.

            Regards

            M Offline
            M Offline
            Marce
            wrote on last edited by
            #5

            @aha_1980 Thanks for your reply. If I add 0.5 + 0.499999999999 a failure also occurs as in this case with 0.999999999999999- My guess is that the start value is 60.99999999999999999999999999999 but the Qdebug shows it as 61.

            The problem is that 60 grade 60 minutes as a 61 ° replacement is unacceptable.

            aha_1980A 1 Reply Last reply
            0
            • M Marce

              @aha_1980 Thanks for your reply. If I add 0.5 + 0.499999999999 a failure also occurs as in this case with 0.999999999999999- My guess is that the start value is 60.99999999999999999999999999999 but the Qdebug shows it as 61.

              The problem is that 60 grade 60 minutes as a 61 ° replacement is unacceptable.

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Marce

              Please give us compileable code and test data.

              Otherwise it's just guessing from our side.

              Regards

              Qt has to stay free or it will die.

              1 Reply Last reply
              1
              • M Marce

                I have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

                I have the following code.

                grade_lat = abs (Lat);
                grade_long = abs(Long);
                min_lat = 60*(abs (Lat) - grade_lat);
                min_long = 60*(abs (Long) - grade_long);
                
                if (min_long >= 60)
                     {
                      min_long -= 60;
                      grade_long++;
                     }
                
                if (min_lat >= 60)
                     {
                      min_lat -= 60;
                      grade_lat++;
                     }
                
                qDebug() << "long calculated: "+QString::number(Long,'f',7)+" grade_long: "+QString::number(grade_long,'f',7)+" min_long: "+QString::number(min_long,'f',7);
                
                qDebug() << "lat calculated: "+QString::number(Lat,'f',7)+" grade_lat: "+QString::number(grade_lat,'f',7)+" min_lat: "+QString::number(min_lat,'f',7);
                

                At one point the QDebug has written the following:

                "long calculated: -61.0000000 grade_long: 60.0000000 min_long: 60.0000000"
                "lat calculated: -31.0000000 grade_lat: 31.0000000 min_lat: 0.0000000"
                

                It is strange that 61 degrees are written as 60 degrees and 60 minutes and for 31 degrees work well.

                If I initialize the variables in 61.0f and 31.0f the QDebug writes well so I guess that in the variable of 61.0 degrees there are actually 60.9999999999999999999999 degrees but I need the Qdebug to write "61 degrees 0 minutes" or write "60 degrees 59.99999999999 minutes".

                How can I implement this without failing?

                Tanks

                Marcelo

                Pablo J. RoginaP Offline
                Pablo J. RoginaP Offline
                Pablo J. Rogina
                wrote on last edited by
                #7

                @Marce said in Float and QString: Strange problem:

                have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

                What about using the class QGeoCoordinate? In particular the toString() method... From documentation:

                Returns this coordinate as a string in the specified format.

                Upvote the answer(s) that helped you solve the issue
                Use "Topic Tools" button to mark your post as Solved
                Add screenshots via postimage.org
                Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                M 1 Reply Last reply
                2
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #8

                  @Marce said in Float and QString: Strange problem:

                  if (min_long >= 60)
                  {
                  min_long -= 60;
                  grade_long++;
                  }

                  if (min_lat >= 60)
                  {
                  min_lat -= 60;
                  grade_lat++;
                  }

                  Is it possible min_lat or min_long are longer than 120?
                  Consider changing to while loops to be more robust:

                  while (min_long >= 60)
                       {
                        min_long -= 60;
                        grade_long++;
                       }
                  
                  
                  while (min_lat >= 60)
                       {
                        min_lat -= 60;
                        grade_lat++;
                       }
                  

                  C++ is a perfectly valid school of magic.

                  M 1 Reply Last reply
                  0
                  • fcarneyF fcarney

                    @Marce said in Float and QString: Strange problem:

                    if (min_long >= 60)
                    {
                    min_long -= 60;
                    grade_long++;
                    }

                    if (min_lat >= 60)
                    {
                    min_lat -= 60;
                    grade_lat++;
                    }

                    Is it possible min_lat or min_long are longer than 120?
                    Consider changing to while loops to be more robust:

                    while (min_long >= 60)
                         {
                          min_long -= 60;
                          grade_long++;
                         }
                    
                    
                    while (min_lat >= 60)
                         {
                          min_lat -= 60;
                          grade_lat++;
                         }
                    
                    M Offline
                    M Offline
                    Marce
                    wrote on last edited by
                    #9

                    @fcarney Thanks for your reply. It's not possible. I have added it on purpose so that the problem is well observed.

                    kshegunovK 1 Reply Last reply
                    0
                    • Pablo J. RoginaP Pablo J. Rogina

                      @Marce said in Float and QString: Strange problem:

                      have a function that returns two double values: Latitude and Longitude and I want to convert it to the format: degrees (integer) and minutes (double).

                      What about using the class QGeoCoordinate? In particular the toString() method... From documentation:

                      Returns this coordinate as a string in the specified format.

                      M Offline
                      M Offline
                      Marce
                      wrote on last edited by
                      #10

                      @Pablo-J.-Rogina Thanks for your reply. My goal is to express the coordinates in degrees in the format:
                      gg mm.mmmmmmm
                      g: degrees
                      m: minutes
                      and with that library it is not possible.

                      1 Reply Last reply
                      0
                      • fcarneyF Offline
                        fcarneyF Offline
                        fcarney
                        wrote on last edited by
                        #11

                        Works for me:

                        #include <QCoreApplication>
                        #include <QDebug>
                        
                        void double_string(double Long, double Lat){
                            int grade_lat;
                            int grade_long;
                            double min_lat;
                            double min_long;
                        
                            grade_lat = abs (Lat);
                            grade_long = abs(Long);
                            min_lat = 60*(abs (Lat) - grade_lat);
                            min_long = 60*(abs (Long) - grade_long);
                        
                            qDebug() << "min_long:" << min_long;
                            qDebug() << "min_lat:" << min_lat;
                        
                            if (min_long >= 60)
                                 {
                                  min_long -= 60;
                                  grade_long++;
                                 }
                        
                            if (min_lat >= 60)
                                 {
                                  min_lat -= 60;
                                  grade_lat++;
                                 }
                        
                            qDebug() << "long calculated: "+QString::number(Long,'f',7)+" grade_long: "+QString::number(grade_long,'f',7)+" min_long: "+QString::number(min_long,'f',7);
                        
                            qDebug() << "lat calculated: "+QString::number(Lat,'f',7)+" grade_lat: "+QString::number(grade_lat,'f',7)+" min_lat: "+QString::number(min_lat,'f',7);
                        }
                        
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication a(argc, argv);
                        
                            double_string(-31.0f,-61.0f);
                            double_string(31.0f,61.0f);
                            double_string(-31.0,-61.0);
                            double_string(31.0,61.0);
                        
                            return a.exec();
                        }
                        

                        Result:

                        min_long: 0
                        min_lat: 0
                        "long calculated: -31.0000000 grade_long: 31.0000000 min_long: 0.0000000"
                        "lat calculated: -61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                        min_long: 0
                        min_lat: 0
                        "long calculated: 31.0000000 grade_long: 31.0000000 min_long: 0.0000000"
                        "lat calculated: 61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                        min_long: 0
                        min_lat: 0
                        "long calculated: -31.0000000 grade_long: 31.0000000 min_long: 0.0000000"
                        "lat calculated: -61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                        min_long: 0
                        min_lat: 0
                        "long calculated: 31.0000000 grade_long: 31.0000000 min_long: 0.0000000"
                        "lat calculated: 61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                        

                        C++ is a perfectly valid school of magic.

                        1 Reply Last reply
                        2
                        • M Marce

                          @fcarney Thanks for your reply. It's not possible. I have added it on purpose so that the problem is well observed.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #12

                          @Marce said in Float and QString: Strange problem:

                          Thanks for your reply. It's not possible. I have added it on purpose so that the problem is well observed.

                          I don't understand the problem. You've just said that the domain is -60 to +60, yet you feed invalid input to the algorithm. There's no algorithm that's consistently going to produce valid data out of invalid input.

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          4
                          • M Offline
                            M Offline
                            Marce
                            wrote on last edited by
                            #13

                            Tanks for your reply. My problem is that a function is returning (supposedly 61 degrees). I need to convert it to the format gg mm.mmmmmmm, that is, 61 ° 00.00000000min, but the attached code shows 60 ° 60.00000000min. Although, 60 ° + 60 minutes = 61 ° is poorly expressed in the QDebug. If I initialize the variable with 61.0 ° the result is correct so I assume that the variable is stored in 60.9999999999999999999999999.

                            kshegunovK 1 Reply Last reply
                            0
                            • fcarneyF Offline
                              fcarneyF Offline
                              fcarney
                              wrote on last edited by
                              #14

                              I can reproduce:

                                  double_string(30.9999999999999999,60.9999999999999999);
                                  double_string(30.99999999999999,60.99999999999999);
                                  double_string(30.999999999999,60.999999999999);
                              
                              "long calculated: 31.0000000 grade_long: 31.0000000 min_long: 0.0000000"
                              "lat calculated: 61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                              "long calculated: 31.0000000 grade_long: 30.0000000 min_long: 60.0000000"
                              "lat calculated: 61.0000000 grade_lat: 60.0000000 min_lat: 60.0000000"
                              "long calculated: 31.0000000 grade_long: 30.0000000 min_long: 60.0000000"
                              "lat calculated: 61.0000000 grade_lat: 60.0000000 min_lat: 60.0000000"
                              

                              You will need to round the number to a lesser precision than the displayed number of 7.

                                  Long = double(int(Long*1000000)/1000000.0);
                                  Lat = double(int(Lat*1000000)/1000000.0);
                              

                              Result:

                              "lat calculated: 61.0000000 grade_lat: 61.0000000 min_lat: 0.0000000"
                              "long calculated: 30.9999990 grade_long: 30.0000000 min_long: 59.9999400"
                              "lat calculated: 60.9999990 grade_lat: 60.0000000 min_lat: 59.9999400"
                              "long calculated: 30.9999990 grade_long: 30.0000000 min_long: 59.9999400"
                              "lat calculated: 60.9999990 grade_lat: 60.0000000 min_lat: 59.9999400"
                              

                              C++ is a perfectly valid school of magic.

                              1 Reply Last reply
                              0
                              • M Marce

                                Tanks for your reply. My problem is that a function is returning (supposedly 61 degrees). I need to convert it to the format gg mm.mmmmmmm, that is, 61 ° 00.00000000min, but the attached code shows 60 ° 60.00000000min. Although, 60 ° + 60 minutes = 61 ° is poorly expressed in the QDebug. If I initialize the variable with 61.0 ° the result is correct so I assume that the variable is stored in 60.9999999999999999999999999.

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #15

                                @Marce said in Float and QString: Strange problem:

                                I need to convert it to the format gg mm.mmmmmmm

                                Which I gave you the solution for. Truncate once to get the degrees and then subtract the whole part, multiply by 60 to get the minutes and that's it.

                                If I initialize the variable with 61.0 ° the result is correct so I assume that the variable is stored in 60.9999999999999999999999999

                                You should realize first that flotaing point numbers are approximations. No real number can be represented exactly, and to add insult to injury not every rational number can be represented exactly. Take the simplest - 1/3, how do you suppose is this represented. Firstly, even in decimal it's 0.33(3), secondly the floating point numbers in computers are powers of 2. There are no common divisors of 2 and 3, so you can get an approximation of 0.33 only, much less something that's infinitely long sequence of 3s. Exactly representable numbers are 1/2 (0.5), 1/4 (0.25), 1/8 (0.125), so any number that can be stored is a sum of such things, nothing more, nothing less.

                                @fcarney said in Float and QString: Strange problem:

                                You will need to round the number to a lesser precision than the displayed number of 7.

                                Long = double(int(Long*1000000)/1000000.0);
                                Lat = double(int(Lat*1000000)/1000000.0);
                                

                                Before doing a multiplication, truncation and division, which is terribly inefficient, have you considered making a simple addition?

                                Long += 0.0000005;
                                

                                Display up to 6 digits and you get your rounding correctly.

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                6
                                • J.HilkJ Offline
                                  J.HilkJ Offline
                                  J.Hilk
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  Theres also qRound to add my 2 cents :)


                                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                  Q: What's that?
                                  A: It's blue light.
                                  Q: What does it do?
                                  A: It turns blue.

                                  1 Reply Last reply
                                  3
                                  • fcarneyF Offline
                                    fcarneyF Offline
                                    fcarney
                                    wrote on last edited by
                                    #17

                                    @kshegunov said in Float and QString: Strange problem:

                                    Long += 0.0000005;

                                    Doesn't that just move the problem though? If it was close to the rounding, adding to the value could put it right at the rounding location. Somehow the value needs to be rounded/truncated to less precision than the display precision or the problem will persist.

                                    C++ is a perfectly valid school of magic.

                                    JonBJ 1 Reply Last reply
                                    0
                                    • fcarneyF fcarney

                                      @kshegunov said in Float and QString: Strange problem:

                                      Long += 0.0000005;

                                      Doesn't that just move the problem though? If it was close to the rounding, adding to the value could put it right at the rounding location. Somehow the value needs to be rounded/truncated to less precision than the display precision or the problem will persist.

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

                                      @fcarney

                                      If it was close to the rounding, adding to the value could put it right at the rounding location

                                      I don't get what you mean by that. So far as I am aware, like @kshegunov I believe that will always mean that truncating the result after the addition at 6 decimal places will give the correctly-rounded result.

                                      1 Reply Last reply
                                      0
                                      • fcarneyF Offline
                                        fcarneyF Offline
                                        fcarney
                                        wrote on last edited by
                                        #19

                                        @JonB said in Float and QString: Strange problem:

                                        I don't get what you mean by that.

                                        Here is a value in which the value output from the function will produce grade 60 min 60:

                                        60.99999999999999
                                        

                                        Yes, adding to that value will produce 61 instead. However if I have this value:

                                        60.99999949999999
                                        
                                        adding 0.0000005 will result in 60.99999999999999
                                        

                                        The problem is just moved to a different location.

                                        C++ is a perfectly valid school of magic.

                                        JonBJ 1 Reply Last reply
                                        0
                                        • fcarneyF fcarney

                                          @JonB said in Float and QString: Strange problem:

                                          I don't get what you mean by that.

                                          Here is a value in which the value output from the function will produce grade 60 min 60:

                                          60.99999999999999
                                          

                                          Yes, adding to that value will produce 61 instead. However if I have this value:

                                          60.99999949999999
                                          
                                          adding 0.0000005 will result in 60.99999999999999
                                          

                                          The problem is just moved to a different location.

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

                                          @fcarney
                                          Somewhere we're talking at cross-purposes.

                                          60.99999949999999 truncate at 6 dps => 60.999999 => correct
                                          60.99999959999999 truncate at 6 dps => 60.999999 => wrong (assuming it's supposed to round to nearest 6 dps)

                                          OTOH :
                                          60.99999949999999 + 0.0000005 = 60.99999999999999 truncate at 6 dps => 60.999999 => correct
                                          60.99999959999999 + 0.0000005 = 61.00000099999999 truncate at 6 dps => 61.000000 => correct too (assuming it's supposed to round to nearest 6 dps)

                                          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