I have a stock selling/buying program, where the user can say how much of a stock they wish to buy and sell. Everything works fine, until the user wants to sell a stock for $4.10 for $5.10. In order to do math easier with the floating point, I convert the double to an int: 10.10 becomes 1010, and so on. Whenever I cast 4.10 to an int, it becomes 409, and the same occurs for 5.10.

The money is stored in a class, Dollars. Inside of this class, when I call a constructor, I can either call Dollars(int cents): cents(cents) {} or Dollars(double dollars): cents(0) { *this = dollars; }. When the double constructor is used, it uses the following cents = (int)(dollars * 100.0); to cast the given double into an int.

I've tried using the (int)(double) cast method inside the class to convert into an int, and I've also tried casting into an int before, and using the int constructor, but neither have worked.

I expect the output of this cast to be 410 when I feed it 4.10, but it always comes out to 4.09.

1 Answers

1
Quimby On

Don't use floats for currency. Also 4.10*100 is likely 409.999999... and conversion to int simply truncates. In this case you will get more precise results by first calling std::round. It won't solve all rounding errors. There still will be cases where the result won't be correct just because double has 52-bit mantissa and int can/will be 64-bit if compiled for x64 platform.

The last problem can be sometimes solved by long double if there's a support for it. That is sizeof(long double)>sizeof(double) which is not guaranteed.

The easiest correct implementation is to simply use uint64_t and do all calculations in e.g. cents. Then all math operations are precise. In real-life when a bank calculates interest it rounds the result too, there's no need for floating precision. Correct printing is then: cout<<amount/100<<"dollars "<<amount%100<<"cents";