【问题标题】:Best way to handle handle input for money处理金钱输入的最佳方式
【发布时间】:2022-01-09 08:29:36
【问题描述】:

所以我正在用 C++ 制作一个基本的银行程序,并有一个接受双精度的存款函数,所以我想处理来自用户的输入,该双精度作为货币有效,因此保留 2 个小数位且不少于0.

解决此问题的最佳方法是什么? 到目前为止我有这个,还有什么我需要检查货币验证或可以用更少的代码行完成的任何事情吗?谢谢

// 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;
            }

【问题讨论】:

  • 永远不要使用 float 或 double 来赚钱。使用整数美分。输入一个字符串,自己解析。
  • @Jeffrey 抱歉,你能解释一下你所说的 intergel 美分数是什么意思吗?
  • 不使用美元计算,而是使用美分。请注意,一美元有 100 美分。根据您使用的任何货币进行调整。
  • long cents250 2.50 美元等等。这样您就不会出现舍入错误。
  • 如果你使用double,当你发现.01 + .02 不是.03 时你会非常难过,因为floating point math is broken

标签: c++ oop error-handling try-catch


【解决方案1】:

您不应该使用双精度或浮点数来存储这些类型的信息。原因是浮点数和双精度数并不像看起来那么准确。

这是 0.1 在二进制中的样子:

>>> 0.1

0.0001100110011001100110011001100110011001100110011...

这是一个如何将 0.1 存储在浮点数中的示例。它是由于删除了无限多的小数位...11001100...,因为我们无法存储它们的所有(无限多):

0.1000000000000000055511151231257827021181583404541015625

所以每个浮点数或双精度数根本不准确。乍一看,我们看不到这一点(因为不准确度非常小 - 对于某些类型的利用),但问题可能会累积 - 如果我们对这些数字进行数学运算。

而银行程序正是这种程序类型,它会导致问题。

我可能会创建一个结构:

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

recalculate() 函数会在您每次需要时将整数转换为“人类如何阅读”。

【讨论】:

  • 这是一个起点。要了解它是如何大规模增长的,请考虑:codereview.stackexchange.com/questions/109821
  • 您可以通过删除dollars 成员来消除或推迟错误。您可能想使用long longint64_t
  • 也看超人三世。
猜你喜欢
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
相关资源
最近更新 更多