使用 4/5 舍入规则对数字进行舍入
Rounding numbers using the 4/5 rounding rule
我目前正在学习 C++。
I have to write a simple class Money
that performs calculations involving dollars and cents where arithmetic has to be accurate to the last cent using the 4/5 rounding rule.
我以前从未处理过货币金额,所以我在理解如何从我的 class 中获得最大收益时遇到了一些麻烦。我知道我不应该用 float
表示货币金额。所以我为 class 使用了两个数据成员来分别存储美元和美分:
long int dollars
long int cents
我的问题是我不知道何时以及如何舍入数字。当我尝试为此 class 实现输入运算符时,我问了自己这个问题。假设用户输入值:12.456, 45.999, 9.54
。
我应该在什么时候四舍五入这些数字?
是先在算术运算中使用,然后对结果进行四舍五入,还是在输入程序时直接四舍五入?
我能说的最好的就是将值作为字符串读取。此时您可以操作每个 item/number,因为字符串本质上是字符数组。
另一种选择是输入强制转换,例如
浮动 x = 10.01; // x = 10.01
(int) y = x; // y = 10
以浮点形式读取值并从那里分解它们。
希望对您有所帮助!
我建议将输入乘以 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 (true)
dollars++; // adjust dollars (dollars = 46)
cents -= 100; // remove 100 from cents (cents = 0)
}
// prints "Amount is .0"
std::cout << "Amount is $" << dollars << "." << cents << "\n";
至于类型转换,它们不是四舍五入的最佳选择。如果您要使用以下代码:
double x = 45.999;
int y = (int)x;
你会得到 y == 45
因为当将任何浮点类型转换为任何整数类型时,小数部分将被完全忽略。
希望对您有所帮助。
我建议您对 cents
执行操作,并仅使用舍入将金额打印到标准输出。
您可以使用 locale facet to parse monetary expressions and std::stringstream, along with stream manipulators 来指定精度,作为实现您想要的 class 的基础结构。
以下是美分和美元之间的换算示例:
int sum_in_cents = 10000;
// stringstream imbued with the local configuration
std::stringstream ss;
ss.imbue(std::locale(""));
// ss contains 0.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);
}
拥有独立的美元和美分成员只会使代码变得不必要的复杂。只需使用美分,然后为 I/O.
重载算术和赋值运算符、构造函数以及可能的 << 和 >>
加法和减法很简单,在这种情况下只是正常的整数运算按比例缩放 100。一般定点division/multiplication需要重新缩放;在这种情况下你可以忽略它,因为用金钱除以或乘以金钱是没有意义的;但是,您可能希望重载货币乘以或除以整数和浮点类型(例如,用于税收、折扣或利息计算)。
通过为金钱重载 << 和 >> 运算符,您可以控制美分值的输入或显示方式 - 通过转换它 to/from dollars.cents
.
在许多情况下可能需要舍入,但在大多数情况下这些可以通过运算符重载来处理。例如,以美元为单位的用户输入可以由赋值运算符和构造函数处理,而利息、税收或份额分配计算可能会产生几分之一的分数,可以通过重载 * 和 / 运算符来处理(尽管可能在内部使用赋值或构造函数,这样你只需要在一个地方四舍五入)。
保持以美分为单位的值并将浮点输入或中间美元值四舍五入为美分,使用 positive/negative 值处理可以按如下方式实现:
long long cents = static_cast<long long>((std::abs(dollars_fp) + 0.005) * 100) ;
if( dollars_fp < 0 )
{
cents = -cents ;
}
我目前正在学习 C++。
I have to write a simple
class Money
that performs calculations involving dollars and cents where arithmetic has to be accurate to the last cent using the 4/5 rounding rule.
我以前从未处理过货币金额,所以我在理解如何从我的 class 中获得最大收益时遇到了一些麻烦。我知道我不应该用 float
表示货币金额。所以我为 class 使用了两个数据成员来分别存储美元和美分:
long int dollars
long int cents
我的问题是我不知道何时以及如何舍入数字。当我尝试为此 class 实现输入运算符时,我问了自己这个问题。假设用户输入值:12.456, 45.999, 9.54
。
我应该在什么时候四舍五入这些数字?
是先在算术运算中使用,然后对结果进行四舍五入,还是在输入程序时直接四舍五入?
我能说的最好的就是将值作为字符串读取。此时您可以操作每个 item/number,因为字符串本质上是字符数组。
另一种选择是输入强制转换,例如
浮动 x = 10.01; // x = 10.01
(int) y = x; // y = 10
以浮点形式读取值并从那里分解它们。
希望对您有所帮助!
我建议将输入乘以 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 (true)
dollars++; // adjust dollars (dollars = 46)
cents -= 100; // remove 100 from cents (cents = 0)
}
// prints "Amount is .0"
std::cout << "Amount is $" << dollars << "." << cents << "\n";
至于类型转换,它们不是四舍五入的最佳选择。如果您要使用以下代码:
double x = 45.999;
int y = (int)x;
你会得到 y == 45
因为当将任何浮点类型转换为任何整数类型时,小数部分将被完全忽略。
希望对您有所帮助。
我建议您对 cents
执行操作,并仅使用舍入将金额打印到标准输出。
您可以使用 locale facet to parse monetary expressions and std::stringstream, along with stream manipulators 来指定精度,作为实现您想要的 class 的基础结构。
以下是美分和美元之间的换算示例:
int sum_in_cents = 10000;
// stringstream imbued with the local configuration
std::stringstream ss;
ss.imbue(std::locale(""));
// ss contains 0.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);
}
拥有独立的美元和美分成员只会使代码变得不必要的复杂。只需使用美分,然后为 I/O.
重载算术和赋值运算符、构造函数以及可能的 << 和 >>加法和减法很简单,在这种情况下只是正常的整数运算按比例缩放 100。一般定点division/multiplication需要重新缩放;在这种情况下你可以忽略它,因为用金钱除以或乘以金钱是没有意义的;但是,您可能希望重载货币乘以或除以整数和浮点类型(例如,用于税收、折扣或利息计算)。
通过为金钱重载 << 和 >> 运算符,您可以控制美分值的输入或显示方式 - 通过转换它 to/from dollars.cents
.
在许多情况下可能需要舍入,但在大多数情况下这些可以通过运算符重载来处理。例如,以美元为单位的用户输入可以由赋值运算符和构造函数处理,而利息、税收或份额分配计算可能会产生几分之一的分数,可以通过重载 * 和 / 运算符来处理(尽管可能在内部使用赋值或构造函数,这样你只需要在一个地方四舍五入)。
保持以美分为单位的值并将浮点输入或中间美元值四舍五入为美分,使用 positive/negative 值处理可以按如下方式实现:
long long cents = static_cast<long long>((std::abs(dollars_fp) + 0.005) * 100) ;
if( dollars_fp < 0 )
{
cents = -cents ;
}