Results 1 to 9 of 9

Thread: modf returns 1 instead of 0

  1. #1
    Join Date
    Jul 2015
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    2

    Default modf returns 1 instead of 0

    This works

    Qt Code:
    1. double myMin, mySec;
    2.  
    3. mySec = modf ( 0.44 * 100, &Min ); // returns desired result
    4.  
    5. // mySec = 0 , myMin = 44 -> this is correct
    To copy to clipboard, switch view to plain text mode 


    This doesn't work, I get incorrect result of myMin = 43 and MySec = 1

    Qt Code:
    1. double myBearing = 172.4400;
    2.  
    3. testMyNum(myBearing);
    To copy to clipboard, switch view to plain text mode 


    Qt Code:
    1. void Delegate::testMyNum(double myDMS) const
    2. {
    3.  
    4. double myMinSec, myDeg, myMin, mySec, multiply100;
    5.  
    6. multiply100 = 100;
    7.  
    8. myMinSec = modf ( myDMS, & myDeg );
    9.  
    10. mySec = modf ( myMinSec * multiply100, &myMin );
    11.  
    12. qDebug() << "myDeg " << myDeg << " myMin " << myMin << " mySec " << mySec;
    13.  
    14. // output -> myDeg 172 myMin 43 mySec 1 -> this is incorrect
    15.  
    16. }
    To copy to clipboard, switch view to plain text mode 


    How do I do this correctly in C++?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,342
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    318
    Thanked 872 Times in 859 Posts

    Default Re: modf returns 1 instead of 0

    What's the value of myMinSec as it is being passed into modf()?

    You are most likely suffering the consequences of the inexact representation of a floating point number in binary. 172.4400 is almost certainly not 172.4400000000000 (or how many digits it actually has) in binary. It's something very close to that but not exactly that.

    If you want to do this exactly, convert your bearing to an integer:

    Qt Code:
    1. int intBearing = int( myBearing * 10000 );
    2. int myDeg = intBearing / 10000;
    3. intBearing -= myDeg * 10000;
    4. int myMin = intBearing / 100;
    5. intBearing -= myMin * 100;
    6. int mySec = intBearing;
    To copy to clipboard, switch view to plain text mode 

    (and if 0.4400 is actually a fraction of a degree, then I think you need some factors of 60 in there to get actual minutes and seconds).

  3. #3
    Join Date
    Jul 2015
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    2

    Default Re: modf returns 1 instead of 0

    Quote Originally Posted by d_stranz View Post
    What's the value of myMinSec as it is being passed into modf()?
    The value of myMinSec is the fractional output of modf (172.4400, &myDeg), so the problem is as you describe.


    Quote Originally Posted by d_stranz View Post
    If you want to do this exactly, convert your bearing to an integer:

    Qt Code:
    1. int intBearing = int( myBearing * 10000 );
    2. int myDeg = intBearing / 10000;
    3. intBearing -= myDeg * 10000;
    4. int myMin = intBearing / 100;
    5. intBearing -= myMin * 100;
    6. int mySec = intBearing;
    To copy to clipboard, switch view to plain text mode 
    Thank you I will try that.

    *edit, unfortunately this doesn't work I will have to try something else.

    Quote Originally Posted by d_stranz View Post

    (and if 0.4400 is actually a fraction of a degree, then I think you need some factors of 60 in there to get actual minutes and seconds).
    This is just a snippet


    Added after 38 minutes:


    Another number issue.

    Qt Code:
    1. QString myBearing = QString::number(172.4499);
    2. qDebug() << myBearing;
    To copy to clipboard, switch view to plain text mode 

    output is "172.45"

    How do I get "172.4499"?

    ok RTFM
    Last edited by qsurvae; 11th July 2015 at 06:47.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: modf returns 1 instead of 0

    You need to understand that floating point data types are unable to represent each and every real number. They approximate values you give them to the nearest possible representation they might find. If you want to be sure no approximation is done, you need to use fixed point arithmetics.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: modf returns 1 instead of 0

    A variation of d_stranz's suggestion to work with integers and some care does work for your coded-decimal values:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QDebug>
    3. #include <cmath>
    4.  
    5. void bearingDecode(double myDMS)
    6. {
    7. bool negative(myDMS < 0.0);
    8. myDMS = fabs(myDMS);
    9. qint32 value = static_cast<qint32>(round(myDMS * 10000.0));
    10. //qint32 value = static_cast<qint32>(myDMS * 10000.0); // to discard fractional "seconds"
    11. qint8 mySec = value % 100;
    12. qint8 myMin = (value / 100) % 100;
    13. qint16 myDeg = value / 10000;
    14. if (negative) myDeg = -myDeg;
    15. qDebug() << "myDeg " << myDeg << " myMin " << myMin << " mySec " << mySec;
    16. }
    17.  
    18.  
    19. int main(int argc, char**argv)
    20. {
    21. QCoreApplication app(argc, argv);
    22. QList<double> testValues;
    23. testValues
    24. << 172.3999 << 172.4400 << 172.4401
    25. << 172.4499 // this one is out-of-bound for 'seconds'
    26. << 172.43999 // this one rounds
    27. << -172.2999; // don't forget negatives if needed
    28. foreach(double testval, testValues) {
    29. bearingDecode(testval);
    30. }
    31. return 0;
    32. }
    To copy to clipboard, switch view to plain text mode 
    Outputs
    Qt Code:
    1. myDeg 172 myMin 39 mySec 99
    2. myDeg 172 myMin 44 mySec 0
    3. myDeg 172 myMin 44 mySec 1
    4. myDeg 172 myMin 44 mySec 99
    5. myDeg 172 myMin 44 mySec 0
    6. myDeg -172 myMin 29 mySec 99
    To copy to clipboard, switch view to plain text mode 


    Are you sure that 172.4400 represents 172°44'00" and not the more usual 172°26'24" ?
    Last edited by ChrisW67; 11th July 2015 at 23:13.

  6. The following user says thank you to ChrisW67 for this useful post:

    d_stranz (12th July 2015)

  7. #6
    Join Date
    Jul 2015
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    2

    Default Re: modf returns 1 instead of 0

    Thanks for the replies.

    I understand the problem, I was after the c++ solution. The above solution may work, I didn't try it yet but I will keep it in mind. I found the easiest solution (for me) was to use strings.

    Qt Code:
    1. error count: 0
    2. 1296000 of 1,296,000 results are correct!
    To copy to clipboard, switch view to plain text mode 

  8. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,342
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    318
    Thanked 872 Times in 859 Posts

    Default Re: modf returns 1 instead of 0

    This calls for a double-facepalm.jpg

  9. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: modf returns 1 instead of 0

    I was not aware that I had slipped back into writing code in CORAL-66

  10. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,342
    Qt products
    Qt5
    Platforms
    Windows
    Thanks
    318
    Thanked 872 Times in 859 Posts

    Default Re: modf returns 1 instead of 0

    My mistake. I thought it was SNOBOL.
    Last edited by d_stranz; 14th July 2015 at 21:24.

Similar Threads

  1. QGraphicsView::itemAt() always returns zero
    By tuli in forum Qt Programming
    Replies: 2
    Last Post: 25th September 2013, 20:36
  2. addapplicationfont always returns -1
    By nick85 in forum Newbie
    Replies: 0
    Last Post: 17th July 2013, 12:08
  3. QApplication::activeWindow always returns '0' on Mac
    By dpatel in forum Qt Programming
    Replies: 1
    Last Post: 14th February 2012, 05:22
  4. QNetworkAccessManager::post() never returns
    By danc81 in forum Qt Programming
    Replies: 2
    Last Post: 21st October 2009, 10:13
  5. app.exec() never returns?
    By stealth86 in forum Qt Programming
    Replies: 3
    Last Post: 17th July 2007, 19:41

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.