0

I'm trying to convert from a price to the smallest currency unit. Eg. when receiving the value 9.45 it should produce the result 945. The conversion code should take a double and convert it to an int while maintaining a two decimal precision.

This C# console code gives me a strange rounding error.

 double val = 9.45d;
 var result = (int)(val * 100);
 System.Console.WriteLine("Result is " + result); // 944

The result of the code snippet is 944 which baffles me. What's wrong?

Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
M Raymaker
  • 1,231
  • 5
  • 14
  • 31
  • `(9.45d).ToString("G17") == "9.4499999999999993"`. Try the same exercise with `9.45m`. – Jeroen Mostert Sep 26 '18 at 14:08
  • 4
    You should not store a price as a double. Currency values should be stored as a decimal. See [decimal vs double! - Which one should I use and when?](https://stackoverflow.com/questions/1165761) – mason Sep 26 '18 at 14:08
  • "convert it to an int while maintaining a two decimal precision"....integers, by definition, don't have decimal places. This information will be lost when you convert it to an int. It will be rounded up/down appropriately to the nearest integer. – ADyson Sep 26 '18 at 14:10
  • 1
    `Math.Round(val*100)` - `(int)` truncates the value – Rafalon Sep 26 '18 at 14:13
  • I see the problem is using a double instead of a decimal. Trying with 9.45m as Jeroen suggest gives me the expected value. The double comes from a contract, so I need to convert this to a decimal. Thanks for the good comments. – M Raymaker Sep 26 '18 at 14:24
  • @MRaymaker Converting it to a decimal doesn't fix the problem. As soon as you've ever stored it in a double you've lost information about that value, and it doesn't matter what you convert it to. You need to *only* store the information in types that are able to store that information accurately. – Servy Sep 26 '18 at 14:31

0 Answers0