对于某些财务计算,我们在浮点数的舍入方面存在问题.
基本上,我们希望将货币金额(如1000000000.555)舍入为2位小数.但是,此数字的浮点表示为1000000000.5549999,因此我们将向下舍入到1000000000.55而不是正确的1000000000.56.
我们有什么方法可以安全地解决这个问题吗?到目前为止我们唯一想到的是在舍入操作之前总是将最小的可表示浮点数添加到金额中,但我们不知道在所有情况下这是否安全.
代码是用C语言编写的,需要在windows32/64/linux/solaris上运行,所以我们很遗憾无法获得像.net中的Decimal数据类型这样的好东西.
任何输入都会有所帮助.
谢谢,里卡德
最常用的表示货币的方法是使用整数.例如,在欧元区,一种常见的方法是用微欧元(1E-6)来表示价值.你显然会使用64位数学.你会在整个应用程序中始终如一地使用它.只有在人类I/O上你才能完成,你可以通过除以10000得到一个整数的分数.
这个故事的寓意永远不会用浮点数代表金钱!
货币是分散的,大多数财务和会计法规都承认这一点.你不能以3.145217美元的身价支付账单.虽然在17世纪,将硬币投入铁匠并让他将一块银币切成碎片是可以接受的(八块碎片有很好的披萨切片标记来帮助这个过程!)今天它是不可能的.
例如,瑞士最小的硬币是5 rappe,因此会计和账单必须表示为最接近的5美分,即您无法获得3.14瑞士法郎的账单,必须是3.15瑞士法郎,或者如果您的供应商不太可能,则为3.10瑞士法郎慷慨,因为你只能支付3.10或3.15现金.
你也有两种选择.获取boost BigDecimal库,它可以精确指定舍入.或者,正如另一张海报所建议的那样,使用long long表示您的金额为千分之一欧元,并且只显示四舍五入.
另一种可能性是使用半美分单位,即55欧元35美分,内部代表11070美分,然后不必担心任何标准会计交易的四舍五入.
我无法担心您没有正确地捕获您的业务要求.在我的上一个项目中,有超过一百页的业务规则处理利率计算,至少40页涉及计算的每个阶段的小数位数或要使用的舍入算法.