将货币金额汇总到最接近的镍,季度,1美元,5美元等面额的最佳方法是什么?

时间:2012-03-31 03:01:08

标签: c++ sql algorithm rounding informix

加拿大宣布他们将不再精打细算,美国财政部正在积极考虑效仿:这意味着货币金额必须四舍五入到最接近的镍,因此需要进行大量的程序修改!在典当行业务中,我们将贷款金额四舍五入到最接近的5美元面额,例如: 50,55,60 ..当计算的贷款介于50美元和100美元之间时,最接近10美元以上的10美元以上等等。其惯常做法是尽量减少使用较小面额的账单。那么什么是四舍五入到最接近的所需面额的好算法?

在SQL中,我可以创建一个用户定义的数据类型来舍入到n面额,或者最好是单独留下十进制(8,2)数据类型并使用函数舍入?

3 个答案:

答案 0 :(得分:3)

假设您的数字类似于: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

答案 1 :(得分:2)

我很想在SQL中使用:

new_val = ROUND(old_value * 20) / 20;

当镍币走向分钱时,那么:

new_val = ROUND(old_value * 10) / 10;

这在SQL中使用DECIMAL或NUMERIC值时效果很好;它也适用于SQL FLOAT,而且SQL SMALLFLOAT的可靠性稍差(因为SMALLFLOAT可能只有大约6位小数的精度)。如果old_valuedouble,则可以在C ++中使用相同的基本技术(如果它是float则更加可疑,原因与SQL SMALLFLOAT有问题相同)。在C ++或C中,您将使用<cmath><math.h>标头获取函数round()roundf()的声明。如果您使用的是ESQL / C和dec_t,那么您需要decround(&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()没有返回值来进行错误检查。使用其中一个输入作为最后一行的输出是安全的。

答案 2 :(得分:1)

这个问题本身不是技术性的答案,但需要考虑的一点。您可能会发现您的“程序化修改”是虚幻的。

当澳大利亚在20世纪90年代逐步淘汰1美分和2美分硬币时,金额的舍入只是在现金交易中进行,情况仍然如此。卡付款按分数计算。同样,电话费和其他水电费也按分数计算,但在柜台现金支付时(并且仅当)以现金支付时四舍五入至最接近的5c。当然,股票交易和货币兑换继续以分数或美分来处理。

所以,如果可以假定现金交易的数量向下舍入(那些在1,2,6或结束7C)是大致为向上四舍五入(3,4,8或9c),则只有同一效果是收银机可能在一天结束时掏出几美分。事实上,它更可能高达几毛钱,因为所有单个项目的交易将四舍五入(例如每$ 3.99购买为$ 4.00钱柜。)

没有 进行任何编程更改以支持逐步淘汰便士。您可以选择在打印的文件上显示舍入的金额,但假设任何人都遇到迷你Y2K或欧元实施问题是不正确的。