PDA

View Full Version : Numeric rounding problems (Again)



vcp
5th March 2010, 14:18
Hi people,

The result of 37635.84/3 is 12545.28, then why the system insists on round off the value for 12545.30?
When I add the result of the division above it is always bigger than the original value .
I need that the value be not arounding. How I can do that?

Thanks in advance.

Lesiok
5th March 2010, 15:07
Show us some code. I think that this is a problem with visualisation. Ie. qDebug() prints double values with one digit after decimal point. So value 12545.2799999999999 is printed as 12545.3. And remeber that float/double type have limited precision. Not all real numbers have double representation. Ie. 37635.84 in double variable looks like 37635.839999999997.

pitonyak
5th March 2010, 16:21
Let me guess, you are using a float, not a double. A float, uses 32 bits to store the number.

First, consider your starting number, 37635.8. This number is not represented exactly the way that the computer stores numbers. The number 3, however, is represented exactly.

Now, consider actual answer. The answer is 12545.266666666666666666666 (the 6 repeats forever). Think of this as 12545.2 + 2/30. A general rule of thumb is that single precision numbers are good to roughly 7 digits.

A floating point number in the computer is represented as:

+/- M * B ^ E

For the computer, the base B is 2.As a single precision or double precision number, the exponent E is 15 and the sign bit is cleared. So, this lives us with:

M * 2 ^ 15 = M * 32768

These are the values for single and double precision (in binary) for M.

1 .00100110000001111010111
1 .0010011000000111101011100001010001111010111000010 100

Now, consider the answer (assuming that it is complete and accurate). With this example, the exponent 16, and the mantissa for the answer is:

1 .10001000000010100010001
1 .1000100000001010001000100010001000100010001000100 010

I think that you might be seeing a pattern... :-)

vcp
5th March 2010, 17:02
Thanks for all replies,



bool MyObject::sum()
{
qdouble s=0.0;
for(int j=0;j<=tblwValues->rowCount()-1;++j) {
QTableWidgetItem *dtValor = new QTableWidgetItem;
dtValor = tblwValues->item(j,1);
if(!dtValor)
continue;
s += dtValor->data(0).toDouble();
}

if(s < leValor->text().toDouble()) {
qDebug() << "less" << QString::number(s,'f',6) << QString::number(leValor->text().toDouble(),'f',6);
return(FALSE);
}

if(s > leValor->text().toDouble()) {
qDebug() << "bigger" << QString::number(s,'f',6) << QString::number(leValor->text().toDouble(),'f',6);
return(FALSE);
}

return(TRUE);

}


example:

item 0: 12545.28
item 1: 12545.28
item 2: 12545.28

Sum: 37635.84 // leValor->text().toDouble()

Always returns FALSE: qDebug() << "bigger" << QString::number(s,'f',6) << QString::number(leValor->text().toDouble(),'f',6);

I really don't I know I'm doing something of wrong

Lesiok
5th March 2010, 17:42
As I told You in previous post. This is a problem with real numbers. Just compile this simple program :

#include <QtCore/QCoreApplication>
#include <QVariant>
#include <QDebug>

int main(int argc, char *argv[])
{
double items[3];

for( int i = 0; i < 3; i++ )
{
QVariant item("12545.28");
items[i] = item.toDouble();
qDebug() << "item[" << i << "]=" << QString::number(items[i],'f',15);
}

double s=0.0;
for( int i = 0; i < 3; i++ )
s += items[i];

qDebug() << QString::number(s,'f',15);
}

Surprised ? If Yes, You must read something about bases of programming.
This is a reason why in databases we have two types of data : double and numeric.
Generally real numbers are not good for money calculating.

vcp
5th March 2010, 18:04
All right, all right, I undertood!

I'm going to use the 'float' and I already did the test and and everything is correctly now