views:

190

answers:

2

Using Java:

The more I read on floating point value comparison, the more I get lost. In case of currency which is usually gets rounded off, what whoule you prefer..using Epsilon or a Big Decimal comparison with scaling?

For instance, your data would range from 0.00 - 49,999.99?

+1  A: 

For a data range of 0 through 50000 with 2 decimal digits, I would use the built-in types with an epsilon.

It really depends on what you're doing with the numbers. If you're just adding or subtracting, you would have to process a large number of numbers to have the floating point errors accumulate to 0.01 for your data range.

Let me explain: let's say your float has 17 significant digits. That means your error for numbers up to 49999.99 may be about 0.000000000001. You would have to add some 10 billion numbers for that cumulative error to reach one cent. Multiplication and division would accumulate that error faster but it would still take quite a while.

If you don't understand how that works (and performance is not the be-all and end-all in your application), use BigDecimal for safety. Built-in types should be a lot faster.

paxdiablo
+1  A: 

Also, when processing currency, there is no reason you cannot simply store an integer representing cents instead of dollars, so that you effectively have a fixed-point representation. eg $4.09 gets stored as 409 and so on. (You may also choose to store tenths of a cent ie 4090 or some other constant fractional precision.) You will be able to add and subtract an infinite number of times without losing precision.

For calculations such as interest, perform the calculation with floating-point numbers and then simply round to the necessary precision before storing. The interest calculation itself will have the necessary precision and you will consistently round to the same number of decimal places each period, which is usually what you want in financial calculations (I've never seen an institution that really wants to keep track of $0.00001 from one pay period to the next -- for legal reasons they will round their books to some specified precision.)

An ordinary signed int storing cents will let you represent up to $21,474,836.47 . You can use a long to store $92,233,720,368,547,758.07. For dealing with more than quadrillions of currency units (representing the US budget in Zim dollars?), use a BigDecimal.

You can learn more about floating point comparisons here: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Crashworks