The BigDecimal
class is the standard way of dealing with monetary units in Java. However, when storing extremely large quantities of data (think millions ~ billions of entries per user) the extra storage space must be considered when compared to primitives such as int
: according to this answer a single BigDecimal
corresponds to about 36 + Ceiling(log2(n)/8.0)
bytes (not including some metadata descriptors and such) whereas an int
is most usually 4
bytes.
When storing millions of entries, this would of course result in a very noticeable increase in not only memory usage but also storage space (e.g. using MongoDB with a descriptor of the type, or the PostgreSQL numeric
type which seems to correspond to at least 8
bytes, I am not familiar with e.g. Cassandra so I am not sure what the storage implications there would be).
An alternative to using the BigDecimal
type would be be to store the integer amount of cents (or whatever the smallest denomination is chosen to be, i.e. $1 == 10000 hundredths of a cent
, as required for precision). This would not only reduce the strain on the program but also reduce the storage required for all but the greatest values in the dataset (which would be outliers anyway and will likely need to be handled separately).
Is this a viable alternative? Are there any pitfalls that must be avoided in this case? Is this approach compliant with current standards (e.g. external audit)?
Note: This only pertains to storing the data, the data would still be displayed with proper formatting to the user depending on various factors (i.e. Locale, e.g. $31,383.22 for US).
Cents is feasible, but one does not entirely escape BigDecimal. Financial calculations like taxes are in most countries required in some precision, like 6 decimals. Also the standard java components do not provide a "virtual" decimal point. From standard output/input, JSF, to JasperReports etcetera.
It should be mentioned that BigDecimal usage is verbose too.
So I would start with BigDecimal, to get a working system fast, and only on massive "spreadsheet" work revert to Cents.