Results 1 to 11 of 11

Thread: toDouble() and rounding problem

  1. #1
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default toDouble() and rounding problem

    Hello, guys. I`ve got a little problem
    I`m using QT4.4.0+VC++2008
    Database SQLite.
    I have 3 double columns in the database:
    1 = 100000.55
    2 = 10000.55
    3 = 1000.55

    I`m selecting those values and displaying in QLabel

    Qt Code:
    1. QSqlQuery query("SELECT * FROM main");
    2. double eur, usd, bgn;
    3. while (query.next()) {
    4. eur= query.value(1).toDouble();
    5. usd = query.value(2).toDouble();
    6. bgn= query.value(3).toDouble();
    7. }
    To copy to clipboard, switch view to plain text mode 

    but there goes the rounding problem:

    1st value goes 100001
    2nd value goes 10000.5
    3rd value goes 1000.55

    What am i missing and how to make 1st value to be shown as 100000.55
    I`ve got alot of calculations and that rounding is a problem. Thanx.

    PS. If i make it "eur= query.value(1).toString();" it shows the correct value but i need to do calculations and at some time i`ll call str.toDouble() and i get the round again.
    Last edited by sadjoker; 27th August 2008 at 15:01.

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

    Default Re: toDouble() and rounding problem

    Rounding shouldn't occur with those values and the double type. Are you sure you are not using float?

    Try running this app:
    Qt Code:
    1. #include <QtCore>
    2. #include "stdio.h"
    3.  
    4. int main(){
    5. str << "100001" << "10000.5" << "1000.55";
    6. foreach(const QString &s, str){
    7. printf("%f\n", s.toDouble());
    8. }
    9. return 0;
    10. }
    To copy to clipboard, switch view to plain text mode 
    It gives me:
    $ ./tst
    100001.000000
    10000.500000
    1000.550000
    Actually it works correctly with floats as well...

    Qt Code:
    1. #include <QtCore>
    2. #include <QtDebug>
    3.  
    4. int main(){
    5. str << "100001" << "10000.5" << "1000.55";
    6. foreach(const QString &s, str){
    7. double d = s.toDouble();
    8. float f = s.toDouble();
    9. qDebug() << d << f;
    10. }
    11. return 0;
    12. }
    To copy to clipboard, switch view to plain text mode 
    yields:
    $ ./tst
    100001 100001
    10000.5 10000.5
    1000.55 1000.55

  3. #3
    Join Date
    May 2008
    Location
    Kyiv, Ukraine
    Posts
    418
    Thanks
    1
    Thanked 29 Times in 27 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: toDouble() and rounding problem

    What if you do this conversion to double within the SQL query?
    I'm a rebel in the S.D.G.

  4. #4
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    I`m using double everywhere. Lemme try your code and i`ll be back.

    Edit:

    Qt Code:
    1. str << "100000.55" << "10000.55" << "1000.55";
    2. foreach(const QString &s, str){
    3. printf("%f\n", s.toDouble());
    4. qDebug() << "qDebug: " << s.toDouble();
    5. }
    To copy to clipboard, switch view to plain text mode 

    This code gives me the next results:

    100000.550000
    qDebug: 100001

    10000.550000
    qDebug: 10000.5

    1000.550000
    qDebug: 1000.55

    Why is that rounding and any idea [in code] how to get the real precise value from the database without the rounding?

    Edit2: Or should i have to use sprintf(), atof() or something like that so i can get the precise value into a double? That`s too... complicated.

    Edit3: wysota, try to put a bigger number with 2 digits after the floating point like 100000.55 and in the second example u gave me it will round the bigger number. It will make it 100001.. thats 0.45 cents gain per calculation. Not good no precise

    Edit4:

    Qt Code:
    1.  
    2. while (query.next()) {
    3. eur = query.value(1).toByteArray();
    4. }
    5. //eur == 100000.55
    6. char *euC = eu.data();
    7. double euDbl = atof(euC);
    8. qDebug() << euC << euDbl;
    9. //result is: 100000.55 100001
    To copy to clipboard, switch view to plain text mode 

    What is wrong here... 5 digits numbers get rounded 1 digit after the point, 6 digits numbers get rounded to an integer. OR nothing is wrong and i`m in the biggest math mistake in my life lol

    100000.55 goes 100001
    10000.55 goes 10000.5
    1000.55 goes 1000.55
    That rounding happens when converting from database result to number (double)
    Is it normal? Or using floats or doubles with currencies is a no no.
    Last edited by sadjoker; 27th August 2008 at 16:56.

  5. #5
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    One more thing... calling

    Qt Code:
    1. cout << setprecision(14) << eu << endl;
    To copy to clipboard, switch view to plain text mode 

    shows exactly what i want... 100000.55 not 100001. But thats only for displaying.

  6. #6
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    OK, i found a solution [very ugly solution]:

    Qt Code:
    1. eu = query.value(1).toDouble();
    2. //eu = 100000.55
    3. cout << setprecision(14) << eu << endl;
    4. //result is 100000.55
    5. //now doing some math
    6. eu += 0.30;
    7. cout << setprecision(14) << eu << endl;
    8. //result is 100000.85
    9. //now converting it to QString and entering back into the database
    10. char result[100];
    11. sprintf( result, "%f", eu);
    12. QString stt = QString(QLatin1String(result));
    13. qDebug() << stt;
    14. //result is "100000.850000"
    15. //GREAT :)
    To copy to clipboard, switch view to plain text mode 

  7. #7
    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: toDouble() and rounding problem

    Quote Originally Posted by sadjoker View Post
    printf("%f\n", s.toDouble());
    qDebug() << "qDebug: " << s.toDouble();
    }

    This code gives me the next results:

    100000.550000
    qDebug: 100001
    You can clearly see here that the problem is not with toDouble(), but qDebug() as you use toDouble() in both lines.

    Quote Originally Posted by sadjoker View Post
    Why is that rounding and any idea [in code] how to get the real precise value from the database without the rounding?
    Seeking precision in floating point values is a mistake. If you need precision, esp. if you are counting big amounts of money, better look for arbitrary precision math library like libapmath or gmplib.


    Quote Originally Posted by sadjoker View Post
    OK, i found a solution [very ugly solution]:

    Qt Code:
    1. eu = query.value(1).toDouble();
    2. //eu = 100000.55
    3. cout << setprecision(14) << eu << endl;
    4. //result is 100000.55
    5. //now doing some math
    6. eu += 0.30;
    7. cout << setprecision(14) << eu << endl;
    8. //result is 100000.85
    9. //now converting it to QString and entering back into the database
    10. char result[100];
    11. sprintf( result, "%f", eu);
    12. QString stt = QString(QLatin1String(result));
    13. qDebug() << stt;
    14. //result is "100000.850000"
    15. //GREAT :)
    To copy to clipboard, switch view to plain text mode 
    Here's a shorter version:
    Qt Code:
    1. eu = query.value(1).toDouble();
    2. ...
    3. QString str = QString::number( eu, 'f', 14 );
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    Wow, thanx jacek. Eventually i would find that static function of QString thank you for pointing it out. This forum is such a great place for finding solutions.
    For me Qt wouldn`t be the same without qtcentre.
    Last edited by sadjoker; 27th August 2008 at 20:29.

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

    Default Re: toDouble() and rounding problem

    Quote Originally Posted by sadjoker View Post
    For me QT wouldn`t be the same without qtcentre.
    But QtCentre has nothing to do with QuickTime...

  10. #10
    Join Date
    Feb 2008
    Posts
    50
    Thanks
    1
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    Another solution is to multiply double values by 100 or 1000 or 10000 (depends of the needed digits after the floating point) before storing them like LONG (int) in the database, and dividing values by 100/1000/10000 after extracting from database and before displaying them.

    The first solution was: extracting as double from the database. Doing some math with the values, converting them to string and storing back into the db.

    Now i have to decide which way to use

  11. #11
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: toDouble() and rounding problem

    I think that the best solution is to use specialized class, something like this http://www.programmersheaven.com/dow...0/ZipView.aspx

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.