-2

it's pretty clear why double & co. are not a good choice when it comes to handling currency. I'm wondering though, since the issue only arises when calculations are performed on the value, am I correct by assuming that there is no problem at all to just store a currency value in a double?

For example: 1. Value gets loaded from any given source into a double 2. Value gets modified, directly typed in by the user. 3. Value gets stored to disk in a suitable format.

In the above example the double is just a way to store the value in memory, and thus shouldn't present any of the problems that arise if calculates are performed on the value. Is this correct?

And, if correct, wouldn't it be better to use currency specific types, only when performing calculations? Instead of loading 1000 BigDecimals from a database one could load 1000 doubles. Then, when necessary, define a BigDecimal, do the calculations and just keep the resulting double in memory.

2
  • 2
    No. When you convert your double to a BigDecimal, you won't get the value you expect. Storing a currency in a double makes it wrong immediately, so don't do it if you're going to be calculating with it later. Unless of course, the error that is introduced is not of concern to the requirements of your program. Commented Nov 15, 2014 at 13:15
  • 2
    If you are careful enough and perform proper rounding while converting to BigDecimal, and you never need more than 14 significant digits, and you always know how many digits to round to, then your approach would be workable. It would still be quite fragile, though. Commented Nov 15, 2014 at 13:19

3 Answers 3

2

No, it still causes problems, even if you don't perform any calculations. The problem is that the value you store might not be exactly representable as a double, so even if you just store it and read it back, you might not get back what you stored.

If you store 0.1 in a double, for instance, you'll find it's not actually 0.1 stored at all, because you can't represent 0.1 exactly in binary.

Sign up to request clarification or add additional context in comments.

4 Comments

But you can round safely back to 0.1. So if you know what precision to round back to, this could work.
@MarkoTopolnik sure. I suppose it depends on the exact workflow. Even if it works for now, it seems like storing up trouble for later down the line when something changes. I wouldn't touch it.
Exactly, that's what I wrote in my comment to the question. There are too many ifs for it to pay off. It's still good to know where exactly the limitations are.
You could always do new BigDecimal(Double.toString(myDouble)) which ought to be fairly reliable.
2

No. A double is never the correct type to store a currency value. Doubles are floating point values, that is, they are basically numbers of the form x * 2^y, where x and y are integers. Thus, some values, such as 0.10 (10 cents) have no exact representation as a double.

Comments

1

The problem here is that when you save say 10.12 in a double variable it may not have a exact double representation, so the java runtime will save it as a closest possible double representation, say 10.1199999999999 or 10.1200000000001 (just an example, I am not sure, have to test). So you get the point, as soon as you put the value in a double variable the currency value is approximated. However, that being said, you can still use a double for calculations and then use appropriate formatting while printing out the values or writing to file, such that the non-significant digits are hidden, depending on your application.

1 Comment

You have chosen 10 1/8 as your example, which is a round binary number. You could have chosen better :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.