0

So I'am making a basic banking program in c++ and have a deposit function that accepts a double, so i want to handle input from the user for a double that is valid as money so to 2 decimal places and not less than 0.

What is the best way to go about this? I have this so far, is there anything else I need to check for money validation or anything that can be done in less lines of code? thanks

// allow user to deposit funds into an account
            try{
                double amount = std::stoi(userInput); // userInput is a string
                if (amount < 0)
                {
                    throw std::invalid_argument("Amount cannot be negative");
                }
                // call function to deposit
                std::cout << "You have deposited " << amount << " into your account." << std::endl;
            }
            catch(std::invalid_argument){
                std::cout << "Invalid input." << std::endl;
            }
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 5
    Never use float or double for money. Use integral number of cents. Input a string and parse it yourself. – Jeffrey Dec 02 '21 at 21:06
  • @Jeffrey sorry can you explain what you mean by intergel number of cents? – mathewsjoyy Dec 02 '21 at 21:10
  • Instead of calculating using dollars use cents. Note that there are 100 cents in a US dollar. Adjust this for whatever currency you are using. – drescherjm Dec 02 '21 at 21:11
  • 1
    `long cents`. `250` for 2.50$ and so on. That way you never getting rounding errors. – Jeffrey Dec 02 '21 at 21:13
  • so we must always use long, no way to use double? – mathewsjoyy Dec 02 '21 at 21:15
  • Ok, you gonna use `double`. How do you explain 3.14159264 dollars? – Thomas Matthews Dec 02 '21 at 21:20
  • 3
    If you use a `double`, you will be very sad when you discover that .01 + .02 is not .03, because [floating point math is broken](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). – Sam Varshavchik Dec 02 '21 at 21:21
  • https://codereview.stackexchange.com/questions/109821/ is a good example of a way to do it. It is even code reviewed :-) – Jeffrey Dec 02 '21 at 21:29
  • @mathewsjoyy -- Many financial companies do not allow usage of plain `double` when calculating values dealing with someone's money. Multiply that tiny round-off error by 10,000, and you are now talking about hundreds, maybe thousands of dollars being lost due to rounding errors. – PaulMcKenzie Dec 02 '21 at 21:46
  • C++11 and later have a [`std::get_money()`](https://en.cppreference.com/w/cpp/io/manip/get_money) stream manipulator for reading monetary input – Remy Lebeau Dec 02 '21 at 21:57

1 Answers1

1

You should never use doubles or floats to store these types of information. The reason is that floats and doubles are not as accurate as they seem.

This is how 0.1 looks in binary:

>>> 0.1

0.0001100110011001100110011001100110011001100110011...

This is an example how 0.1 is stored in a float. It is caused by cutting out infinite number of decimal places of ...11001100..., because we are not able to store all (infinite number) of them:

0.1000000000000000055511151231257827021181583404541015625

So every float or double is not accurate at all. We can not see that at first sight (as the inaccuracy is really small - for some types of utilization), but the problem can accumulate - if we would do math operations with these numbers.

And a bank program is exactly the type of program, where it would cause problems.

I would propably create a structure:

struct Amount {
      int dollars;
      int cents;
      
      void recalculate() {
            dollars += cents / 100;
            cents = cents % 100;
      }
};

Where the recalculate() function would convert the integers to "how human would read it" every time you need it.