# [ACCEPTED]-Is a double really unsuitable for money?-currency

Score: 120

Very, very unsuitable. Use decimal.

``````double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false
``````

(example 1 from Jon's page here - recommended reading ;-p)

Score: 35

You will get odd errors effectively caused 5 by rounding. In addition, comparisons with 4 exact values are extremely tricky - you 3 usually need to apply some sort of epsilon 2 to check for the actual value being "near" a 1 particular one.

Here's a concrete example:

``````using System;

class Test
{
static void Main()
{
double x = 0.1;
double y = x + x + x;
Console.WriteLine(y == 0.3); // Prints False
}
}
``````
Score: 7

Yes it's unsuitable.

If I remember correctly 27 double has about 17 significant numbers, so 26 normally rounding errors will take place 25 far behind the decimal point. Most financial 24 software uses 4 decimals behind the decimal 23 point, that leaves 13 decimals to work with 22 so the maximum number you can work with 21 for single operations is still very much 20 higher than the USA national debt. But rounding 19 errors will add up over time. If your software 18 runs for a long time you'll eventually start 17 losing cents. Certain operations will make 16 this worse. For example adding large amounts 15 to small amounts will cause a significant 14 loss of precision.

You need fixed point datatypes 13 for money operations, most people don't 12 mind if you lose a cent here and there but 11 accountants aren't like most people..

edit
According 10 to this site http://msdn.microsoft.com/en-us/library/678hzkk9.aspx Doubles actually have 15 to 9 16 significant digits instead of 17.

@Jon 8 Skeet decimal is more suitable than double 7 because of its higher precision, 28 or 29 6 significant decimals. That means less chance 5 of accumulated rounding errors becoming 4 significant. Fixed point datatypes (ie integers 3 that represent cents or 100th of a cent 2 like I've seen used) like Boojum mentions 1 are actually better suited.

Score: 5

Since `decimal` uses a scaling factor of multiples 7 of 10, numbers like 0.1 can be represented 6 exactly. In essence, the decimal type represents 5 this as 1 / 10 ^ 1, whereas a `double` would represent 4 this as 104857 / 2 ^ 20 (in reality it would 3 be more like really-big-number / 2 ^ 1023).

A `decimal` can exactly 2 represent any base 10 value with up to 28/29 1 significant digits (like 0.1). A `double` can't.

Score: 4

My understanding is that most financial 10 systems express currency using integers 9 -- i.e., counting everything in cents.

IEEE 8 double precision actually can represent all 7 integers exactly in the range -2^53 through 6 +2^53. (Hacker's Delight, pg. 262) If 5 you use only addition, subtraction and multiplication, and 4 keep everything to integers within this 3 range then you should see no loss of precision. I'd 2 be very wary of division or more complex 1 operations, however.

Score: 4

Using double when you don't know what you 22 are doing is unsuitable.

"double" can represent 21 an amount of a trillion dollars with an 20 error of 1/90th of a cent. So you will get 19 highly precise results. Want to calculate 18 how much it costs to put a man on Mars and 17 get him back alive? double will do just 16 fine.

But with money there are often very 15 specific rules saying that a certain calculation 14 must give a certain result and no other. If 13 you calculate an amount that is very very 12 very close to \$98.135 then there will often 11 be a rule that determines whether the result 10 should be \$98.14 or \$98.13 and you must follow 9 that rule and get the result that is required.

Depending 8 on where you live, using 64 bit integers 7 to represent cents or pennies or kopeks 6 or whatever is the smallest unit in your 5 country will usually work just fine. For 4 example, 64 bit signed integers representing 3 cents can represent values up to 92,223 2 trillion dollars. 32 bit integers are usually 1 unsuitable.

Score: 0

No a double will always have rounding errors, use 1 "decimal" if you're on .Net...

More Related questions