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.
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.
There is no way to get
BigDecimal
precision on adouble
.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 anint
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):