Reply
Thread Tools
Posts: 650 | Thanked: 619 times | Joined on Nov 2009
#1
I have floating point computation in Qt C++, and I am having precision issues. The function is called in Javascript and the argument is floating point.

Code:
Q_INVOKABLE QVariantList FileHandler::calcUniSymPerf (const int i, const float price) {
...
}
Let's say the price argument is 34.82, and when I use qDebug() to print out price variable it is 34.82, but converting it to QString using QString::number(price, 'f', 8) gives me 34.81999969. I try to round the price to two decimal points:

Code:
    
// Code 1
    float nearestPrice = (floor(price * 100 + 0.005)); 
    nearestPrice = nearestPrice/100;
// Code 2
    float nearestPrice = (floor(price * 100 + 0.005))/100.0;
    qDebug() << "nearest=" << QString::number(nearestPrice,'f',8);
The results for code 1 and code 2 are different. Code 1 gives me the 34.82000000 I wanted, but code 2 gives me 34.81999969.
Further down the code, I want to calculate the market value by mutiplying price and share (QVariant converted to float).

Code:
    float value   = price * uniShare.at(i).toFloat();
The share is 30005, so the correct value is 1044774.10, but the program gives me 1044774.06.Even multiplying 34.81999969*30005 should be 1044774.09.

I am at a lost. Can anyone educate me on why the floating point calculations are not working?
 
Posts: 329 | Thanked: 422 times | Joined on Feb 2011 @ derpton
#2
One of the very important rules of programming:

NEVER EVER USE FLOATING POINT FOR MONEY!!!!

Seriously.

Instead, store it as an integer in cents, so in your instance it would become just 3482, and you pass around this nice and round number without worries.

Floating point rounding errors WILL accumulate over time and give you serious headaches and differences in the bottom line.
 

The Following 2 Users Say Thank You to herpderp For This Useful Post:
erendorn's Avatar
Posts: 738 | Thanked: 983 times | Joined on Apr 2010 @ London
#3
float will give you approx 7 decimals of precision, always (hence asking for 8 digits is asking for trouble). It's very bad. Don't use floats unless you can control rounding errors, and don't have a choice (say, you are doing GPU calculations and need the x4 perf).
Use doubles (approx 16 decimals) if you are doing fractional calculations, or integers if you are dealing with real money.

Also, float are stored in binary, so there are no reason that you can write an arbitrary integer value as a float (there may be one above and one below, but none equal).
 

The Following 3 Users Say Thank You to erendorn For This Useful Post:
Reply

Thread Tools

 
Forum Jump


All times are GMT. The time now is 06:18.