**double**values. I am trying to understand why 100 * A * B * C is not same as A * B * C * 100 if A, B, C are double values. Here is a code snippet to observe the case.

The output for the following code snippet is like -

aValue * bValue * cValue = 9127.335

multiplicationResult = 9127.335

aValue * bValue * cValue * 100 = 912733.4999999999

multiplicationResult = 912733.4999999999

100 * aValue * bValue * cValue = 912733.5

multiplicationResult = 912733.5

Why is it different and how can I make them behave as same whether mupltiply 100 at the beginning or at the end of the calculation?

Ashik Uzzaman

Senior Software Engineer, TubeMogul, Emeryville, CA, USA.

double * double * double * int

so its equivalent to (double*double*double)*int

I think we are losing some precision when we are multiplying double(64 bit) with int(32 bit)

second case

int*double*double*double

so overall first int is getting multiplied with double..you can try something like this:

100*(a*b*c)

Thanks and Regards,

SCJP 1.5 (90%), SCWCD 1.5 (85%), The Jovial Java, java.util.concurrent tutorial

Originally posted by Ashik Uzzaman:

multiplicationResult1 = 912733.4999999999

multiplicationResult2 = 912733.5

Because you are using floating point.

They are the same according to the rules of floating point.

The proper way to compare floats and doubles is

If you want it to work like money, don't use float, use BigDecimal

**float**and

**double**data types do not have infinite precision, so you can expect rounding errors to occur.

Note that 912733.4999999999 and 912733.5 are practically the same number. The difference between those numbers is 0.00000000001.

If such small differences are important to you, you shouldn't use the

**double**data type. Use BigDecimal instead, which gives you arbitrary precision.

Originally posted by Jesper Young:

Note that 912733.4999999999 and 912733.5 are practically the same number.

In the float/double world, they are the same.

You can't tell how long the 9999 repeats, what we see printed is just the convenient output of the print formatter, not the actual value internally.

If there is no meaningful difference, they are the same.

Sometimes I wish that languages didn't have float/double, they are constantly misused.

Yes, you can. Pass it to the constructor of a BigDecimal and print out the BigDecimal unformatted.Originally posted by Pat Farrell:

You can't tell how long the 9999 repeats.

It just goes to show how imprecise floating-point is.

The reason floating-point arithmetic is useful is that there are people like engineers who used to use slide rules (I still have one myself), and they don't care whether they get a result of breakingStrain = 24.9 or 25; they will engineer to withstand 30 regardless! Using BigDecimal for that sort of calculation would necessitate specifying precision and rounding convention for division, and there would be a performance overhead.

To be general-purpose, a language must be able to support the significant minority of applications that do serious maths, with numbers of widely-varying magnitude. This includes many types of graphics, printing, modelling of physical processes and even some types of games.

For numbers of widely-varying magnitude, you can't sensibly use integer types, because, while you can include an implicit scale factor, that scale factor has to be fixed.

You can use things like BigDecimal for widely-varying magnitudes, but calculations in BigDecimal are much slower, and take far more memory, than they do with floating-point. Sometimes, that doesn't matter, but in plenty of cases it does.

Perhaps, the compiler needs a "Clippy" that springs up and says: -

"I see you're using floating-point. Would you like some help with that?"

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.

Ashik Uzzaman

Senior Software Engineer, TubeMogul, Emeryville, CA, USA.

Originally posted by Ashik Uzzaman:

So other than using BigDecimal, one way to get the constant result back is to use parenthesis correctly and in order.

Sorry, this is incorrect. For your example problem, proper use of parenthesis can "fix" the problem, but for another set of numbers, or different terms, it will still be "wrong"

The problem is fundamental to floating point, and double. It can not be solved in general, other than saying "don't use floating point" in cases where precision is expected. Floating point was designed for engineering. It works great there.

Originally posted by Peter Chase:

Perhaps, the compiler needs a "Clippy" that springs up and says: -

"I see you're using floating-point. Would you like some help with that?"

Ashik Uzzaman

Senior Software Engineer, TubeMogul, Emeryville, CA, USA.

There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors

That works in the present case, but in future if you want precision in arithmetic you canOriginally posted by Ashik Uzzaman:

The following one will give me a constant result no matter what the parenthesis placement is. This might solve my problem, at least partially.

Originally posted by Campbell Ritchie:

A BigDecimal with a double argument will simply perpetuate the imprecision in the double.

Indeed. It's worse than that, in the example above, though. The BigDecimal constructor is being called with a "double"

**expression**as an argument. The setScale() method is then being used to gloss over the resulting mess.

Euyukk! Wrong!

If you want guaranteed total accuracy, floating point must not appear anywhere in the calculation.

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.

You can't use float or double and get what you want. See upthread suggest for a trivial test.

Float considered harmful

When the precision setting is not 0, the rules of BigDecimal arithmetic are broadly compatible with selected modes of operation of the arithmetic defined in ANSI X3.274-1996 and ANSI X3.274-1996/AM 1-2000 (section 7.4).

**RE:**:

Originally posted by Pat Farrell:

Use integer (with implied cents, pence, etc.) or fixed point arithemtic which looks a lot like integer.(...snip...)

Source: Comemnts in source code for BigDecimal.

[ May 31, 2008: Message edited by: Nicholas Jordan ]

"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."

Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |