Win a copy of The Way of the Web Tester: A Beginner's Guide to Automating Tests this week in the Testing forum!

# Precision in Java

saurabh mahajan
Greenhorn
Posts: 5
In Java, the precision is lost when i convert a float value to double or do an operation(add, subtract, multiply, divide) on float/double values. To overcome, this i convert the operands to long and then apply operation. But the problem is for very large values, the result after multiplication operation is overflowed. And it cannot be determined that the operation has overflowed or not. eg. The result of large values can be positive or negative. It cannot be ascertained. Any suggestions.....

Jim Yingst
Wanderer
Sheriff
Posts: 18671
What you you mean, precision is lost when you convert a float value to a double? Or when you perform an operation with float or double values? This makes no sense to me. You would lose precision converting from double to float, but not the reverse. Do your calculations using double - you'll be fine. The roundoff error in your answers will be far too small to matter to anyone. Really.
OK, there are a small number of applications that actually do require more precision than this. If you really have need for it, you can use the BigDecimal class. But only use this if you have a good idea of what the term "significant digits" means, and are certain that your application requires more of them.

saurabh mahajan
Greenhorn
Posts: 5
well, if you set 13.3 to a float variable and assign that variable to a double variable, there will be noticable loss of precision. In my case, the precision is utmost important. also the bigdecimal is the good solution, but it is quite slow. Sometimes it is 2000 times or more slow than primitive operations.

Jim Yingst
Wanderer
Sheriff
Posts: 18671
How do you notice this loss?

saurabh mahajan
Greenhorn
Posts: 5
just print both the values. you will come to know.

Jim Yingst
Wanderer
Sheriff
Posts: 18671
Ah. You aren't seeing loss of precision. You are seeing imprecision which was already present in the float datatype, revealed explicitly by casting to a more precise type. Look at the output of the following:
<code><pre> for (float x = 13.3f; x < 30; x += 0.3f) {<br /> double y = x;<br /> System.out.println("float: " + x + " -> double: " + y);
}
</pre></code>
You will see that overall, the float values are no more accurate than the double values. It's just that the system doesn't bother printing out more than eight significant digits for a float (and obviously the eighth is usually wrong, but it's at least close), because there's no point - the additional digits would be completely wrong. But for a double, the system typically prints around 17 digits, because doubles are usually capable of at least 16 digits which are exactly correct. Why aren't they correct in this case? Because the values came from a float, which is much less accurate. It's like taking a photograph with a dirty lens, and then complaining because your expensive projection system won't focus the picture correctly. The problem isn't the projector; it's the original image. Similarly in this case, if you aren't happy with the results of converting a float to a double, don't use any floats at all in your calcaulations. Try the following program for comparison:
<code><pre> for (double x = 13.3; x < 30; x += 0.3) {<br /> float y = (float) x;<br /> System.out.println("double: " + x + " -> float: " + y);
}
</pre></code>
As you see the answers are much more accurate. The float results way look more accurate, but again, that's just because they have been rounded off from the double values. Note that all the results here are much, much more accurate than those in the first program.
[This message has been edited by Jim Yingst (edited July 18, 2001).]