Sophtware
Sophtware

Reputation: 1824

Multiplying a double value by 100.0 introduces rounding errors?

This is what I am doing, which works 99.999% of the time:

((int)(customerBatch.Amount * 100.0)).ToString()

The Amount value is a double. I am trying to write the value out in pennies to a text file for transport to a server for processing. The Amount is never more than 2 digits of precision.

If you use 580.55 for the Amount, this line of code returns 58054 as the string value.

This code runs on a web server in 64-bit.

Any ideas?

Upvotes: 7

Views: 11219

Answers (8)

murgatroid99
murgatroid99

Reputation: 20277

My suggestion would be to store the value as the integer number of pennies and take dollars_part = pennies / 100 and cents_part = pennies % 100. This will completely avoid rounding errors.

Edit: when I wrote this post, I did not see that you could not change the number format. The best answer is probably using the round method as others have suggested.

EDIT 2: As others have pointed out, it would be best to use some sort of fixed point decimal variable. This is better than my original solution because it would store the information about the location of the decimal point in the value where it belongs instead of in the code.

Upvotes: 0

ULysses
ULysses

Reputation: 978

Try

((int)(Math.Round(customerBatch.Amount * 100.0))).ToString()

Upvotes: 3

jdot
jdot

Reputation: 811

Decimal has more precision than a double. Give decimal a try.

http://msdn.microsoft.com/en-us/library/364x0z75%28VS.80%29.aspx

Upvotes: 0

yatagarasu
yatagarasu

Reputation: 549

no, multiplying does not introduce rounding errors but not all values can by represented by floating point numbers. x.55 is one of them )

Upvotes: 0

Justin Ethier
Justin Ethier

Reputation: 134157

You really should not be using a double value to represent currency, due to rounding errors such as this.

Instead you might consider using integral values to represent monetary amounts, so that they are represented exactly. To represent decimals you can use a similar trick of storing 580.55 as the value 58055.

Upvotes: 0

Donald Miner
Donald Miner

Reputation: 39893

I'm guessing that 580.55 is getting converted to 58054.99999999999999999999999999..., in which case int will round it down to 58054. You may want to write your own function that converts your amount to a int with some sort of rounding or threshold to make this not happen.

Upvotes: 4

Andrew Bezzub
Andrew Bezzub

Reputation: 16032

You could use decimal values for accurate calculations. Double is floating point number which is not guaranteed to be precise during calculations.

Upvotes: 8

Jesper Palm
Jesper Palm

Reputation: 7238

You should really use decimal for money calculations.

((int)(580.55m * 100.0m)).ToString().Dump();

Upvotes: 21

Related Questions