I am currently developing an ERP (Enterprise Resource Planning) system and need to make decisions regarding the type of data to use for handling calculations and other numerical values within the application.
I know that Java offers several options for handling decimal numbers, such as BigDecimal and Double. I understand that each has its own advantages and disadvantages, but I want to ensure that I choose the most appropriate one to maintain precision and efficiency in my system.
Here are some specific contexts where I need to apply calculations:
I am inclined to use BigDecimal for financial operations due to the precision it offers, but I am concerned about the impact on performance. On the other hand, Double might be more efficient in terms of speed but could introduce rounding errors.
What recommendations do you have for handling these cases in an ERP? In which situations would it be preferable to use BigDecimal and when Double? Are there any patterns or best practices I should follow?
Floating-point technology trades away accuracy for speed of execution.
In Java, the primitive types float
and double
are floating point types. So are their wrapper classes, Float
and Double
. Never use these where accuracy matters. That means never for money.
BigDecimal
or whole integersInstead, fractional money amounts must be handled in one of these approaches:
BigDecimal
objects. This type is much slower than floating-point, but accurate. The syntax is clumsier than numeric literals, of course. But on the up-side, besides accuracy, you get handy methods such as Banker’s Rounding.long
). To track USD to the tenth of a cent, multiply by a thousand to represent mills (₥).Type | Example | Notes | Pros | Cons |
---|---|---|---|---|
Floating-pointfloat & double |
1.23d |
Never use for money | Fast execution. Convenient use as literals. | Inaccurate. |
BigDecimal | new BigDecimal( "1.23" ) |
Accurately represents fractional amounts. | Handy methods, such as Banker’s Rounding. | Slow. Clumsy syntax. |
Whole integerint & long |
long cents = new Double( 1.23d * 100 ).longValue() ; |
Requires that you multiply fractional inputs, and divide to get fractional outputs. | Fast execution. Simple type, with direct matching types in database. | May be confusing to naïve programmer & user. (Be sure to label clearly and consistently such as cents or mills .) |
Joda-Money library | Money money = Money.parse("USD 23.87") ; |
Explicitly built for the problem of handling money amounts and math. | Handles both fixed-precision and variable-precision | Not standardized. |