I am trying to establish some concise overview of what options for precise caluclations we have in JAVA+SQL. So far I have found following options:
- use doubles accepting their drawbacks, no go.
- use BigDecimals
- using them in complicated formulas is problematic for me
- use String.format/Decimal.format to round doubles
- do i need to round each variable in formula or just result to get BigDecimal precision?
- how can this be tweaked?
- use computed fields option in SQL.
- drawback is that I'd need dynamic SQL to pull data from different tables + calculate fields on other calculated fields and that would get messy
any other options?
Problem statement:
I need precise financial calculations that would involve using very big (billions) and very small numbers (0.0000004321), and also dividing values that are very similar to each other, so for sure I need precision of BigDecimal.
On the other side, I want to retain ease of use that doubles have in functions (i work on arrays from decimal SQL data), so calculations like: (a[i] - b[i])/b[i] etc. etc. that are further used in other calculations. and I'd like to have users to be able to desing their own formulas as they need them (using common math statements)
i am keen to use "formatting" solution for String.format, but this makes code not very readable ( using String.format() for each variable...).
Many thanks for suggestion of how to deal with the stuff.
There is no way to get BigDecimal
precision on a double
. double
s have double precision.
If you want to guarantee precise results use BigDecimal
.
You could create your own variant using a long
to store the integer part and an int
to store the fractional part - but why reinvent the wheel.
Any time use double
s you stand to stuffer from double precision issues. If you use them in a single place you might as well use them everywhere.
Even if you only use them to represent data from the database then will round the data to double precision and you will lose information.
There is nothing you can do to avoid floating point erros in float and double.
No free cheese here - use BigDecimal.
From Effective Java (2nd ED):
Item 48: Avoid float and double if exact answers are required
Float and double do not provide exact results and should not be used where exact results are required.
The float and double types are particularly ill-suited for monetary claculations because is impossible to represent 0.1 (or any other negative power of ten) as a float or double exactly.
The right way to solve this problem is to ouse BigDecimal, int, or long for monetary calculations.
...
An alternative is to use int or long and to keep track of the decimal point yourself.
If I understand your question, you want to use Data Types with more precision than the native Java ones without loosing the simple mathematical syntax (e.g. / + * - and so on). As you cannot overload operators in Java, I think this is not possible.