Reputation: 5247
I have a csv file where amount and quantity fields are present in each detail record except header and trailer record. Trailer record has a total charge values which is the total sum of quantity multiplied by amount field in detail records . I need to check whether the trailer total charge value is equal to my calculated value of amount and quantity fields. I am using the double data type for all these calculations
In the csv file amount field appears as "10.12" or "10" or "10.0" or "10.456" or "10.4555" or "-10.12". Also amount can have a positive or negative value.
In csv file
H,ABC.....
"D",....,"1","12.23"
"D",.....,"3","-13.334"
"D",......,"2","12"
T,csd,123,12.345
------------------------------ While Validation i am having the below code --------------------
double detChargeCount =0;
//From csv file i am reading trailer records charge value
String totChargeValue = items[3].replaceAll("\"","").trim();
if (null != totChargeValue && !totChargeValue.equals("")) {
detChargeCount = new Double(totChargeValue).doubleValue();
if(detChargeCount==calChargeCount)
validflag=true;
-----------------------While reading CSV File i am having the below code
if (null != chargeQuan && !chargeQuan.equals("")) {
tmpChargeQuan=Long(chargeQuan).longValue();
}
if (null != chargeAmount && !chargeAmount.equals("")) {
tmpChargeAmt=new Double(chargeAmount).doubleValue();
calChargeCount=calChargeCount+(tmpChargeQuan*tmpChargeAmt);
}
I had declared the variables tmpChargeQuan, tmpChargeAmt, calChargeCount as double
When i searched web i came to know that double might give issues for financial calculations so need to use BIGDECIMAL. But i am wondering is this scenario applies for my calculation. In my case amount value can have upto 5 or 6 digits after the decimal point" Can i use double datatype for this calculation? I am using it for validation. Will it create an problem if i use the above code with multiplication using double?
Upvotes: 1
Views: 3932
Reputation: 29878
I'll expand on what Adeel has already succintly answered. You can fit those numbers into a double datatype. The problem is when numbers get calculated, will they get calculated correctly? The answer is no - they will not. Generally it's not that much of a problem if you account for that with a delta, that is, your leeway in assuming whether or not a double value is equivalent to another double value. But for calculations involving exact numbers, such as monetary calculations, you must use a type such as BigDecimal to hold the values.
When you have this number: 1.23445 as a double, it may look like 1.23445 but it may actually be something like 1.234450000003400345543034
When you perform multiple calculations on numbers such as that, generally those extra places don't matter - however, over time, they will yield inaccurate results. With BigDecimal, when a number is specified as its String representation, it is that number - it does not suffer the "almost as good" problem doubles do.
I am updating this answer to include some notes from the double constructor of BigDecimal, found at this address.
The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
Upvotes: 4
Reputation: 39907
Its not the matter of size, its a matter of expressing floating point numbers exactly. How the BigDecimal Class Helps Java Get its arithmetic right.
Upvotes: 2