Sign in to follow this  
cignox1

[java] fixed point class

Recommended Posts

I need to handle monetary values for financial operations and AFAIK, floating point math is not really a good thing in those cases due to rounding errors.
I could use double and force it to round it to two or three numbers after the decimal point when I print it, but I wonder if this is the usual way to go in these applications (I dont't like to do a simple addition like 245.50 + 14.15 and get 259.640000000000000002 :-(

Share this post


Link to post
Share on other sites
I don't know of a fixed point class. But why would you expect that answer? The answer would more likely be 259.65. Moreover, you are far more likely to get such rounding artifacts with fixed point arithmic. The usual way is certainly using floats.

Alternatively, for fixed precision monetary values, sometimes the computations are done in cents, using only integer arithmic. This way, you will always get exactly the right amount. It is somewhat like fixed point arithmic only without the implementation difficulties. You can just use the Java integer.

Illco

Share this post


Link to post
Share on other sites
Thanks for your answers. Yes, actually I meant decimal, not exactly fixed point. I found this. It seems to have a limited license, but I don't plan to sell my program (I do it for my gf) so There should be no problems using it.

Quote:

But why would you expect that answer? The answer would more likely be 259.65.

No, I would expect it to result 259.65, but actually I got some strange rounding errors (the listed addition was only an example, I don't remember the real values involved).

EDIT: mmm, apparently the BigDecimal class (improved in java 1.5 api following the request of IBM) just does this...

[Edited by - cignox1 on October 23, 2005 12:15:36 PM]

Share this post


Link to post
Share on other sites
Boy this is elementary programming question. Rouding errors caused by number representation.
BTW I suspect that number was 259.650000000000000002, other version of the problem would be 259.649999999999999998. As you clearly see majority of digits is correct, you just need round few least important digits, so first number would be 259.650000000000000002 - 0.000000000000000002 = 259.65
second would be 259.649999999999999998 + 0.000000000000000002 = 259.65


Doubles are used even in banking operations, they are just rounded properly to nearest even number before showing the result to user (to don't scare him). They are also rounding after exponential calculations. If you need to know when number representation errors would become significant, you could calculate it as a simple exercise.

Share this post


Link to post
Share on other sites
Quote:

Boy this is elementary programming question. Rouding errors caused by number representation.



Thank you, I did the homeworks ;-)
Seriously, I know that floating point representations lead to rounding errors, that's why I asked for a decimal representation, that should make them dramatically less evident than with binary, because 0.1(for example) can be represented exactly.

Yes, I thought to keep doubles because BigDecimal would make me modify 2000+ codelines (and I don't feel like, really). If only java permitted operator overloading, moving from double to BigDecimal would have been easier :-(

Share this post


Link to post
Share on other sites
One thing to remember is that operator overloading could easily be replaced by a function. By creating a replaceall macro in your IDE from 'x+y' to 'BigDecimal.add(x,y)' is a small feat, especially in comparison to rewriting 2000 lines of code.

Share this post


Link to post
Share on other sites
Quote:
Original post by H_o_p_s
One thing to remember is that operator overloading could easily be replaced by a function. By creating a replaceall macro in your IDE from 'x+y' to 'BigDecimal.add(x,y)' is a small feat, especially in comparison to rewriting 2000 lines of code.


Wouldn't this replace all x+y occurrencies (so integers, strings and other types as well?).

Share this post


Link to post
Share on other sites
Because the correspondent solution to Numeric data type in SQL is the BigDecimal class. I know he didn't mention databases and SQL, but for currency values, the use of BigDecimal is widespread.

Son Of Cain

Share this post


Link to post
Share on other sites
Quote:
Original post by Son of Cain
Err.. Can't BigDecimal and NumberFormatter handle it for you?


Yes, the class I found by IBM was an improvement of the BigDecimal class because they find it not so good (I don't know why) in the 1.4 sdk (but IIRC they changed it in the 1.5). I thought to use BigDecimal, but then I understood that it would have required a lot of code changes, and I'm not sure I feel like making them. Currently I use double, so I hope that the precision is high enaught to avoid rounding errors after the 2nd decimal number. I will round the doubles just before displaying them to the user, and then see what happens.
I told my gf that the app is currently in alpha stage, so she is aware that she cannot trust ;-)
What do you think about this solution? Could it lead to problems?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this