programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Jeanne Boyarsky
• Ron McLeod
• Paul Clapham
• Liutauras Vilda
Sheriffs:
• paul wheaton
• Rob Spoor
• Devaka Cooray
Saloon Keepers:
• Stephan van Hulst
• Tim Holloway
• Carey Brown
• Frits Walraven
• Tim Moores
Bartenders:
• Mikalai Zaikin

# Loss of precision worry when using Math.pow()

Ranch Hand
Posts: 140
• Number of slices to send:
Optional 'thank-you' note:
Hi guys,

Don't know if this question belongs in the advanced or beginners java section, so am putting in the intermediate section. Hope this is right, but please move if not.

I have a worry when it comes to floating point values loss of precision. Maybe you guys can help to substiate my worry, or provide a solution to it.

I'm writing a financial application that it working with decimal numbers. Therefore i can't use float or double. Use bigdecimal instead. I need to take 'a decimal value' to the power of 'another decimal value'.

There is the function Math.pow(double a, double b) that returns a double.

If I do this for example:

BigDecimal one = new BigDecimal("1.234");
BigDecimal two = new BigDecimal("1.5");

So my question is, will there be a loss of precision for the variable 'answer' when I call the Math.pow method?

cheers
Darryl

Darryl Nortje
Ranch Hand
Posts: 140
• Number of slices to send:
Optional 'thank-you' note:
Just to expand a little....

When I do the above in the windows calculator I get

1.3707957192813231133678705725098

And when I run the above program in eclipse I get

1.370795719281323155058771590120159089565277099609375

So there is a descrepancy... Has loss of precision occured, or is windows calculator rounding off.

How would one do this if in fact loss of precision has occured in the Math.pow method call.

cheers
Darryl

Ranch Hand
Posts: 94
• Number of slices to send:
Optional 'thank-you' note:
Maybe, run it and get the answer and compare it using a calculator that is accurate to as many places as you can find.

That specific example isn't all that complex, so it should be fairly accurate. It is equivilent to square root of 1.234^3. My Ti-85 graphing calculator returns 1.37079571928, which is precise enough for most applications.

Running the program with 1.5 on Linux the result returned is 1.3707957192813232, without using BigDecimal at the end, using it before the pow90 call is pointless. Is this precise? No, since the real result is irrational, you will never have precision. How precise you need, depends on the situation. 4 significant digits might be peachy in one case, and death or massive problems in another.
[ September 13, 2006: Message edited by: Robert Hill ]

Darryl Nortje
Ranch Hand
Posts: 140
• Number of slices to send:
Optional 'thank-you' note:
Hi there,

Thanks for the reply. I'm not quite sure I follow. Albeit that my example might be bad, there probably is instances where even the rounding off wouldn't help. If you look at example below, it is much much simpler, yet even with rounding gives the totally incorrect result.

double x = 1.0;
double y = 0.8;

System.out.println(x - y);

prints out 0.19999999999999996.

So perhaps ignore my example and how close it is to the real answer. There might be some doubles when you call Math.pow() that also give totally incorrect results that not even rounding will help.

So is there some other way (using BigDecimal) that you can do something similar to Math.pow() without loosing precision.

cheers
Darryl

Java Cowboy
Posts: 16084
88
• Number of slices to send:
Optional 'thank-you' note:
First you say that you are deliberately not using float and double because you don't want to loose precision, but then you show a piece of code that does convert your BigDecimals to doubles and back. So you are using doubles, even though you just said you didn't want to use them. Ofcourse the precision will not be better than what double provides if you do that.

The types float and double store floating point numbers in binary form. Just like you cannot express some numbers exactly in decimal form, such as 1/3 = 0.33333..., there are numbers that you cannot express exactly in binary form.

The number 0.2 in binary form is written as: 0.00110011001100110011... Note the recurring pattern, just like 0.3333... in decimal; the number just can't be represented exactly in binary form.