Results 1 to 6 of 6

Thread: Floating point imprecision

  1. #1
    Join Date
    May 2006
    Posts
    58
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Floating point imprecision

    OK, I have been programming in C++ for over 10 years now and I've never run into this problem...I've always known that floating point operations are somewhat "fuzzy", but I always assumed it would be down to a resolution that I never encounter...well, in a point of sale app I wrote using QT, I am finding that for purchases totaling over $13,000 I am getting imprecision down to 0.1 (I'm running into 5 cents off)

    At first I thought I was crazy, but after doing tons and tons of printfs, it seems that something flaky is going on. I have a function called RoundMoney that does a floor and a couple of divisions to force the float value to two decimal places. What's odd is that when I echo the value with qDebug:

    qDebug() << fValue

    I get the result I'd expect (I think it's 13125.2) ...but when I use

    printf("%.5f\n", fValue);

    I am getting the values that are off by a nickel (13125.240 or something close...I don't have my debug output in front of me) Note that my arithmetic comparisons (greater than, less than) reflect the value reported by printf and NOT the qDebug output. If anything, the qDebug output is "wrong" because it doesn't agree with the actual if( x < y ) comparisons I'm making. Basically my code looks roughly like this:

    if( fOwed > fPaid ) {
    printf("%.3f owed, %.3f paid\n", fOwed, fPaid);
    qDebug << fOwed << " owed " << fPaid << " paid";
    }

    And my output (roughly) is:
    13125.240 owed, 13125.200 paid
    13125.2 owed, 13125.2 paid

    How does QT "know" to truncate that .04??

    I am looking for one of two possible solutions:

    1) Do whatever the hell it is that QT is doing internally to "know" that I earlier truncated my value and ignore the remaining "imprecise" floating point values

    2) Use something besides floating point values and arithmetic. Trolltech seems to have thought of everything with QT, is there some sort of high level "decimal" or "money" class to deal with this?
    Last edited by hardgeus; 3rd August 2006 at 02:58.

  2. #2
    Join Date
    Jan 2006
    Location
    Shanghai, China
    Posts
    52
    Thanks
    3
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Floating point imprecision

    IMO, it's just like cout, qDebug has a default precison when print a float, and it happened to be 0.1. But it will not do any harm to your program, it's just an output, so what are u worrying about...?
    1. Users don't have the manual, and if they did, they wouldn't read it.
    2. In fact, users can't read anything, and if they could, they wouldn't want to.

  3. #3
    Join Date
    May 2006
    Posts
    58
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Floating point imprecision

    Quote Originally Posted by bood
    IMO, it's just like cout, qDebug has a default precison when print a float, and it happened to be 0.1. But it will not do any harm to your program, it's just an output, so what are u worrying about...?
    What I'm worried about is that my software checks to see if the customer is underpaying. You can't have the customer give the cashier a $5 bill to pay a $10 tab. The problem is that once the amount gets large enough, there can be up to a nickel of error. So, yesterday when a customer tried to make a $13125.20 purchase, and paid exactly $13125.20 from their credit card, the software thought that he wasn't paying enough because the variable storing the amount owed was actually $13125.24.

    I don't think this is just a problem with qDebug() truncating. I am rounding all of my float values to two significant digits (cents), and I use QString::number() all over my code. Now, it WILL format to just one digit if the final digit is a "0", but it doesn't just automatically truncate to .1 every time. Even qstring::number is seeing the value, which is 13125.24 as 13125.2

    I considered the possibility that I am making a mistake (which of course I still may be), but if QString::number() were always truncating to .1 then my users CERTAINLY would have noticed because every total would always be even.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Floating point imprecision

    Try:
    Qt Code:
    1. if( fOwed > fPaid ) {
    2. printf("%.3f owed, %.3f paid\n", fOwed, fPaid);
    3. qDebug << fixed << fOwed << " owed " << fPaid << " paid";
    4. }
    To copy to clipboard, switch view to plain text mode 
    and better don't use floating point numbers for large amounts of money.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Floating point imprecision

    Quote Originally Posted by hardgeus
    Even qstring::number is seeing the value, which is 13125.24 as 13125.2
    The docs say:
    QString QString::number ( double n, char f = 'g', int prec = 6 ) [static]
    Here's a small test:
    Qt Code:
    1. #include <QtDebug>
    2. #include <QString>
    3.  
    4. int main()
    5. {
    6. qDebug() << QString::number( 13125.24567 );
    7. qDebug() << "f";
    8. qDebug() << QString::number( 13125.24567, 'f', 1 );
    9. qDebug() << QString::number( 13125.24567, 'f', 2 );
    10. qDebug() << QString::number( 13125.24567, 'f', 3 );
    11. qDebug() << "g";
    12. qDebug() << QString::number( 13125.24567, 'g', 6 );
    13. qDebug() << QString::number( 13125.24567, 'g', 7 );
    14. qDebug() << QString::number( 13125.24567, 'g', 8 );
    15. }
    To copy to clipboard, switch view to plain text mode 
    Output:
    "13125.2"
    f
    "13125.2"
    "13125.25"
    "13125.246"
    g
    "13125.2"
    "13125.25"
    "13125.246"
    As you can see everything depends on what you order QString::number() to do.

  6. #6
    Join Date
    May 2006
    Posts
    58
    Thanks
    12
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Floating point imprecision

    Quote Originally Posted by jacek
    The docs say:

    As you can see everything depends on what you order QString::number() to do.
    That's the problem...What was happening is I was assigning the values I pulled from the database into my amount textbox using:

    txtAmount->setText( QString::number(fValue) );

    This was truncating my cents when the value got over 10,000! Then, later, when I pulled it out of the textbox, the value was wrong. I was using the qDebug() to print, and this was masking the error since it was also truncating the cents. This error ONLY occurred when values were over 10,000 (which is unusual in my app) so the problem rarely occurred.

    I'm glad this was the problem. I was starting to think that I didn't understand the behavior of floating point numbers!

Similar Threads

  1. Replies: 3
    Last Post: 20th April 2006, 11:21

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.