我正在学习C ++。
我必须编写一个简单的
class Money
来执行涉及美元和美分的计算,其中算术必须使用4/5舍入规则精确到最后一分。
我以前从未处理过金额问题所以我在理解如何从班上取得最佳成绩时遇到了一些麻烦。我知道我不应该用float
代表货币金额。所以我使用两个数据成员为我的班级分别存储美元和美分:
long int dollars
long int cents
我的问题是我不知道何时以及如何对数字进行舍入。当我试图为这个类实现一个输入操作符时,我问自己这个问题。假设用户输入值12.456, 45.999, 9.54
作为输入。
我应该何时对这些数字进行舍入?
我应该先在算术运算中使用它们,然后将结果四舍五入,或者在它们输入程序时将它们直接舍入?
答案 0 :(得分:2)
拥有单独的美元和分元会使代码变得比必要的更复杂。只需使用美分,然后重载算术和赋值运算符,构造函数和可能的<<和>>用于I / O.
加法和减法是微不足道的,只是在这种情况下缩放100的正常整数运算。通常,定点除法/乘法需要重新缩放;在这种情况下,你可以忽略这一点,因为用金钱划分或乘钱是没有意义的;您可能希望过载货币乘以或除以整数和浮点类型(例如,税务,折扣或利息计算)。
通过重载<<和>>为了赚钱,您可以控制美分值的输入或呈现方式 - 将其转换为dollars.cents
。
在许多情况下,可能需要进行舍入,但在大多数情况下,这些可以通过运算符重载来处理。例如,美元的用户输入可以由赋值运算符和构造函数处理,而可能导致分数为1美分的利息,税收或股份分配计算可以通过重载*和/运算符来处理(尽管可能在内部使用赋值或构造函数,这样你只需要在一个地方进行舍入。)
保持以美分为单位并将浮点输入或中间美元值四舍五入到分数,可以通过以下方式实现正/负值处理:
long long cents = static_cast<long long>((std::abs(dollars_fp) + 0.005) * 100) ;
if( dollars_fp < 0 )
{
cents = -cents ;
}
答案 1 :(得分:1)
我建议您在cents
上执行操作,并仅使用舍入将金额打印到标准输出。
您可以使用locale构面来解析货币表达式,并使用std::stringstream和stream manipulators来指定精度,作为实现所需类的基础结构。
以下是美分与美元之间转换的示例:
int sum_in_cents = 10000;
// stringstream imbued with the local configuration
std::stringstream ss;
ss.imbue(std::locale(""));
// ss contains $100.00 (assuming a en_US locale configuration)
ss << std::showbase << std::put_money(sum_in_cents);
此外,还有a boost library货币格式。
注意:传统的4/5舍入由标准库函数round()
执行。如果你想自己实现一些东西,你可以这样做:
double round (double n)
{
return (n > 0.0) ? floor(n + 0.5) : ceil(n - 0.5);
}
如果您想要四舍五入的整数结果,则不需要ceil()
或floor()
:
int round (double i)
{
return (i > 0.0) ? (i + 0.5) : (i - 0.5);
}
答案 2 :(得分:0)
我能说的最好的是以字符串形式读取值。此时您可以操作每个项目/数字,因为字符串基本上是字符数组。
另一种选择是输入,例如
float x = 10.01; // x = 10.01
(int)y = x; // y = 10
以浮点形式读取值并将其从那里分解。
希望这有帮助!
答案 3 :(得分:0)
我建议将输入乘以1000左右,以使输入成为一个整数,这样您在其上进行的操作就更准确了。舍入后,您可以使用整数除法来查找美元,使用余数运算符来获得美分(乘以10)。至于你的第二个问题,你应该至少在舍入之前将数字转换为整数美元和美分,然后你可以选择你喜欢的数字。以下是舍入输入的示例:
/* Note: Code untested */
double x;
std::cin >> x; // x = 45.999
long y = x * 1000; // y = 45999
int dollars = y / 1000; // dollars = 45
int cents = y % 1000 // cents = 999 (divide by 10 to get real # of cents)
if (cents % 10 >= 5) { // if last digit should be rounded up (true)
cents += 10; // add 10 (cents = 1009)
cents -= (cents % 10); // remove the last digit (cents = 1000)
}
else if (cents % 10 < 5) { // if last digit should be rounded down (false)
cents -= (cents % 10); // remove last digit
}
cents /= 10; // make cents a factor of 100 instead of 1000 (cents = 100)
if (cents >= 100) { // if cents more than $1 (true)
dollars++; // adjust dollars (dollars = 46)
cents -= 100; // remove 100 from cents (cents = 0)
}
// prints "Amount is $46.0"
std::cout << "Amount is $" << dollars << "." << cents << "\n";
对于类型转换,它们不是舍入的最佳选择。如果您要使用以下代码:
double x = 45.999;
int y = (int)x;
您会得到y == 45
,因为在将任何浮点类型转换为任何整数类型时,小数部分将被完全忽略。
希望这有帮助。