The combination of forgetting my numerical methods class, the numerous bug reports on the bug parade, and the automatic rounding of floats and doubles when printing (but not after casting a float to a double) threw me. I apologize for confusing anyone who read the article, especially to new Java programmers. I present two better solutions to the problem:
The first possible solution is to always specify the desired rounding explicitly with NumberFormat
. In my case, I use the float and double to represent dollars and cents; therefore, I need only two significant digits. Listing C3.1 demonstrates how to use the NumberFormat
class to specify a maximum of two fraction digits.
Listing C3.1 FormatNumbers.java
import java.text.*; public class FormatNumbers { public static void main(String [] args) { try { NumberFormat fmt = NumberFormat.getInstance(); fmt.setMaximumFractionDigits(2); float f = 100.28f; System.out.println("As a float : " + f); double d = f; System.out.println("Cast to a double : " + d); System.out.println("Using NumberFormat: " + fmt.format(d)); } catch (Throwable t) { t.printStackTrace(); } } }
When we run the FormatNumbers
program, it produces:
E:\classes\com\javaworld\jpitfalls\article2>java FormatNumbers As a float : 100.28 Cast to a double : 100.27999877929688 Using NumberFormat: 100.28
As you can see -- regardless of whether we cast the float to a double -- when we specify the number of digits we want, it properly rounds to that precision -- even if the number is infinitely repeating in binary. To circumvent this pitfall, control the formatting of your doubles and floats when converting to a String
.
A second, simpler solution would be to not use a float to represent cents. Integers (number of pennies) can represent cents, with a legal range of 0 to 99. You can check the range in the mutator method.
Next time
In my next column, I'll present another pitfall from java.lang
, as well as two traps hiding in the java.net
and the Swing
packages. If you know of any Java pitfalls that have wasted your time and caused you frustration, please email them to me so we can save others the same fate.
Learn more about this topic
- Download the source code for all the examples in this article
http://www.javaworld.com/jw-12-2000/traps/jw-1229-traps.zip - Java Pitfalls, Time Saving Solutions, and Workarounds to Improve Programs, Michael C. Daconta, Eric Monk, J. Paul Keller, Keith Bohnenberger (John Wiley & Sons, 2000)
http://www.amazon.com/exec/obidos/ASIN/0471361747/javaworld - Review the
JConfig
library or download it for evaluation
http://tolstoy.com/samizdat/jconfig.html - Read Michael Daconta's previous Java Traps column, "Steer Clear of Java Pitfalls" (JavaWorld, September 22, 2000)
http://www.javaworld.com/javaworld/jw-09-2000/jw-0922-pitfalls.html - Browse JavaWorld's Topical Index
http://www.javaworld.com/javaworld/topicalindex/jw-ti-index.html