初学者练习:设计货币 class

Beginner exercise : Design a Money class

我实际上正在学习 C++ 编程语言(我以前从未编程过),我正在尝试解决一个问题,我必须设计和实现一个简单的货币 class 来进行涉及美元的计算。作者给了我一些规则来遵循如何实现这个 class :

在编码之前进行一些研究后,我发现不建议将双精度类型用于货币金额,我应该使用整数。我的问题是关于如何在不丢失数据的情况下读取 double 作为输入并将其转换为 long int?我应该使用其他 way/types 来做到这一点吗?我应该直接为此 class 将 long int(代表美分)作为构造函数参数吗?我一直在搜索,但我发现了很多关于可能丢失数据的信息,这让我感到困惑。这是一个初学者练习,所以我不认为计算应该非常精确。谢谢

我们假设输入的格式正确。

也就是说,您收到的所有货币金额都将采用

的形式
99.99

其中 9 符号可以是 0 到 9 之间的任何数字(含 0 和 9)。小数点左边只有数字,范围小到可以存储在int.

小数点右侧(始终有一个小数点)始终是一个正数,也符合 int.

您可以创建一个非常简单的结构来表示货币金额,将美元分成一个 int,将美分分成另一个:

struct Money
{
    int dollars;
    int cents;
};

读入金额后,您将首先读入 dollars 字段。然后你会读入一个.。然后你会在cents字段中读到:

Money m;
char c;
std::cin >> m.dollars >> c >> m.cents;

Live Demo

了解了这么多之后,您可以开始让 I/O 更健壮,处理没有小数点的情况,或者有人输入非常大的数字。在这一点上,首先读入 std::string 以获得你的钱的文本表示,然后从那里解析 string:

可能是合理的
Money m{0,0};
std::string text;
std::getline(std::cin, text);
std::cout << "Input was: " << text << std::endl;

// is there a decimal point?
size_t decimal_point_position = text.find_first_of('.');
m.dollars = stoi(text.substr(0, decimal_point_position));
if (decimal_point_position != std::string::npos)
{
    decimal_point_position += 1;
    m.cents = stoi(text.substr(decimal_point_position, text.size() - decimal_point_position));
}

Demo2

从那里您可以继续提高输入的稳健性。如果有两位小数呢?如果输入中有字符怎么办?

我建议你编写几个测试来测试尽可能多的输入可能性,假设是有史以来最愚蠢、最多 computer-illiterate 的用户。你应该如何处理无效输入?要求更多,抛出异常,使用默认值并打印警告?所有这些都是您将来在处理用户输入时做出的决定。

编辑: 解决你的最后一点

arithmetic operations need to be accurate to the last cent using the 4/5 rounding rule.

这一般不会太难,只是很乏味。您 运行 遇到的最大障碍将是分裂。此时您需要非常小心整数舍入。即:

2/1 将产生 0,而不是 0.5

不应执行乘法和除法运算,因为它们没有意义。在网上搜索一下如何使用整数除法准确舍入。