将货币金额四舍五入到最接近的镍、四分之一、1 美元、5 美元等面额的最佳方法是啥?

Posted

技术标签:

【中文标题】将货币金额四舍五入到最接近的镍、四分之一、1 美元、5 美元等面额的最佳方法是啥?【英文标题】:What's the best way to round monetary amounts to the nearest nickel, quarter, $1, $5, etc. denominations?将货币金额四舍五入到最接近的镍、四分之一、1 美元、5 美元等面额的最佳方法是什么? 【发布时间】:2012-03-31 03:01:08 【问题描述】:

加拿大宣布他们将不再铸造便士,美国财政部正在强烈考虑效仿!这意味着货币金额必须四舍五入到最接近的五分之一,因此需要对程序进行大量修改!.. 在典当行业务中,我们一直将贷款金额四舍五入到最接近的 5 美元面额,例如50, 55, 60.. 当计算的贷款在 50 美元和 100 美元之间,到 100 美元以上的最接近的 10 美元面额,等等。它的常见做法是尽量减少使用较小面额的钞票。那么,什么是四舍五入到最接近的所需面额的好算法呢?

在 SQL 中,我可以创建一个用户定义的数据类型来四舍五入到 n 面额,还是单独保留 decimal(8,2) 数据类型并使用函数进行四舍五入更好?

【问题讨论】:

这是作业吗?很确定美国财政部还没有宣布这样的事情。 另外,您是在寻找 SQL 解决方案,还是通用解决方案? 今天在 ABC 新闻上,是的,我正在寻找 SQL 和 C++ 解决方案 @FrankComputer 我认为你的意思是加拿大停止使用便士而不是美国 abcnews.go.com/blogs/headlines/2012/03/… 嗯,我听说不一样,我听说美国也会这样做!...这是有道理的,节省原材料、制造、时间消耗等。 【参考方案1】:

假设您的数字类似于:44.32,那么您需要做的就是(这是伪代码,c++ 中的实现应该很简单):

findmod = (num_to_be_changed*100)%5
if findmod <= 2
  new_num = num_to_be_changed - findmod
else 
  new_num = num_to_be_changed +  (5 - findmod)
end
new_num = new_num/100

【讨论】:

【参考方案2】:

我很想在 SQL 中使用:

new_val = ROUND(old_value * 20) / 20;

当五分硬币变成美分时,那么:

new_val = ROUND(old_value * 10) / 10;

这在具有 DECIMAL 或 NUMERIC 值的 SQL 中运行良好;它也适用于 SQL FLOAT,但适用于 SQL SMALLFLOAT 的可靠性稍差(因为 SMALLFLOAT 可能只有大约 6 位十进制数字的精度)。如果old_valuedouble,则可以在C++ 中使用相同的基本技术(如果是float,则更可疑,原因与SQL SMALLFLOAT 存在问题的原因相同)。在 C++ 或 C 中,您将使用 &lt;cmath&gt;&lt;math.h&gt; 标头来获取函数 round()roundf() 的声明。如果您使用的是 ESQL/C 和dec_t,那么您需要decround(&amp;dec_value, 0);

在 ESQL/C 中,您已经提供了四舍五入的位数,并且您还必须编写乘法和除法的代码。假设你有一个十进制值 dec_20 包含值 20,你会写:

dec_t new_val;
decmul(&old_val, &dec_20, &new_val);
decround(&new_val, 0);
decdiv(&new_val, &dec_20, &new_val);

您可能会错误检查decmul()decdiv()decround() 没有返回值来进行错误检查。使用其中一个输入作为最后一行的输出是安全的。

【讨论】:

【参考方案3】:

本身不是对该问题的技术回答,而是需要考虑的一点。你可能会发现你的“程序化修改”是虚幻的。

当澳大利亚在 1990 年代逐步淘汰 1 美分和 2 美分硬币时,仅对现金交易进行四舍五入,现在情况仍然如此。信用卡付款按美分收费。同样,电话费和其他水电费按美分收费,但在(且仅当)在柜台以现金支付时四舍五入到最接近的 5c。当然,股票交易和货币兑换仍以几美分或几美分的价格进行。

因此,如果您可以假设向下取整的现金交易数量(以 1、2、6 或 7c 结尾的那些)与向上取整的数字(3、4、8 或 9c)大致相同,那么唯一的效果是收银机在一天结束时可能会损失几美分。事实上,它更有可能上涨几美分,因为所有单项交易都将被四舍五入(例如,每 3.99 美元的购买是 4.00 美元。)

没有必须进行任何编程更改来支持逐步淘汰便士。您可以选择在打印的案卷上显示四舍五入的金额,但假设任何人都因迷你 Y2K 或欧元实施问题而陷入困境是不正确的。

【讨论】:

澳大利亚可能就是这种情况,但加拿大和其他国家可能是另一回事。我假设大多数或所有商家都会更改其产品和服务的定价,四舍五入到最接近的所需面额。 嗯。想想看。如果他们这样做了,那么首先就没有问题需要处理! 真的吗?...再想想吧!

以上是关于将货币金额四舍五入到最接近的镍、四分之一、1 美元、5 美元等面额的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Python - 按四分之一间隔舍入

Stripe Currency - 所有金额都以美分/百分之一为单位,还是取决于货币?

PHP number_format():将数字四舍五入,然后格式化为货币

将分钟向下舍入到最接近的一刻钟

Pandas - 将时间戳四舍五入到最接近的秒数

将时间四舍五入到最接近的秒数 - Python