I'm trying to make this program where you got some different items you can buy.
im storing my prices in a sqlite database (have not decided on datatype other than its going to be string or integer).
i have read for 2 hours now trying to get a hang on this, i understand why i cant use doubles or float values.
but i cant decide: should i store my prices as integers? or Strings.
the problem i see here is that i have ALWAYS been told not to store integers as strings.. and now people tell me it smarts because this is the only way i can keep the accuracy of my prices ?
if i store them as integers i will have a problem of:
int 5 / 100 //i want that to be 0.05
int 50 / 100 //i want that to be 0.50
int 500 / 100 //i want that to be 5.00
how do i do this without using doubles ??
or maybe there is a way to do it with BigDecimals?
BigDecimal bddd1 = bdd1.setScale(2,RoundingMode.HALF_EVEN); // gives me 5.00 instead of 0.05
so how will i do this correctly, always getting 2 decimals.
As others have suggested, you can use integers to store the number of cents, but then you can get into problems if you must calculate percentages, or divide amounts (of cents) by, say, 12 months. Then you may need an intermediate that is more accurate.
BigDecimals provide all this. Internally, they are scaled integers, so they provide everything you need.
It is quite simple to store 5 cents, initialising with a string:
BigDecimal fiveCents = new BigDecimal("0.05");
or, calculating:
BigDecimal oneCent = new BigDecimal("0.01");
BigDecimal fiveCents = BigDecimal.valueOf(5).multiply(oneCent);
or
BigDecimal fiveCents = BigDecimal.valueOf(5).movePointLeft(2);
or whatever you like, just use your imagination. But do not use doubles or floats to initialize your BigDecimals, as these can be inaccurate when they have a fractional part. Use strings or use integers and divide by 100, or multiply by one hundredth or move the decimal point left by 2.
I have seen voices that think that using BigDecimals to represent currency values is wrong, and that you rather use (scaled) integers, but BigDecimals are exactly that: scaled integers. And for "small" numbers (below the maximum long value), BigDecimals even use a long and not a BigInteger to represent the unscaled value.
Do not round too early, except if certain calculatory rules demand it. Otherwise, only round (setScale()
) at the end.