11

你有什么建议:

  1. 补偿Money 对象集合的批量数学运算中的累积错误。这是如何在您的语言环境的生产代码中实现的?
  2. 会计四舍五入背后的理论。
  3. 任何有关主题的文献。

我目前正在阅读Fowler。他提到了 Money 类型,它是典型的结构(int、long、BigDecimal),但没有提及策略。

关于四舍五入的旧帖子(这里这里)没有提供我需要的细节和形式。

我在 inet 中发现的想法与“四舍五入”有关,这是平衡错误的最佳方法。

感谢帮助。

4

6 回答 6

7

记录财务数据时存在许多舍入问题。第一个问题是存储和检索精确十进制数字的能力

  • 大多数数据库都提供十进制数据类型,您可以在其上指定小数点前后的位数(货币的小数位数也不同,我已经处理了具有 0、2、3 位小数的货币)
  • 在处理这些数据时,如果您想避免应用程序端出现任何意外的舍入错误,您可以使用BCD作为通用方法,或者您可以使用整数来表示任何固定的十进制表示法或混合您自己的

如果解决了第一个问题,则任何加法(或减法)都不会引入任何舍入误差。乘以整数也是如此。

第二个问题,在您能够在不丢失信息的情况下存储和检索数据之后,预计会由于除法(或乘以非整数)而导致舍入错误。

例如,如果您的货币格式允许 2 位小数,并且您想要存储记录余额为 10 到 3 个相等的借方的交易,您只能将其存储为

10.00  
-3.33  
-3.33  
-3.33  

-0.01 

(舍入误差)

无论选择何种数据类型存储选择,这都是预期的问题,如果您希望帐户平衡,则需要注意这一问题。这种情况主要是通过除法(或通过与具有许多有效数字的非整数相乘)引入的。

解决此问题的一种方法是验证您的数据在此类操作后是否平衡,并识别允许的舍入差异而不是错误情况。

编辑:至于对文学的引用,这一篇似乎很有趣,而且不会太长,并且涉及到相当广泛的观众和有趣的场景。

于 2010-05-19T09:52:50.627 回答
4

使用银行家的四舍五入。你四舍五入到最接近的两便士。

http://www.xbeat.net/vbspeed/i_BankersRounding.htm

您可以在此基础上展开以舍toward入最接近的两便士。所以 22.5 轮到 22,但 23.5 轮到 24。23.1 和 22.9 都轮到 23。但是,原始庄家算法更流行。

于 2010-05-18T19:36:01.767 回答
4

永远不要将货币值存储在 double 或 float - 使用intorlong因为无法将 0.1 准确地存储为二进制。

于 2010-05-18T19:47:45.007 回答
3

这完全取决于应用程序。希望没有太多需要四舍五入的情况。例如,将资金从一个帐户转移到另一个帐户不需要四舍五入。

对于需要四舍五入的情况,只要您选择一个策略、进行沟通并坚持下去,您做什么并不重要。例如,我相信我的储蓄账户的利息会四舍五入到最接近的一美分。

于 2010-05-19T04:31:21.410 回答
2

您应该做什么可能会根据您所在的市场或司法管辖区的惯例而有所了解。例如,澳大利亚市场的债券定价要求您将某些中间操作四舍五入到小数点后 8 位。最终价格被引用到特定的小数位数(我认为是 3)。

如果您正在处理会计应用程序,我希望您的法律环境的相关会计标准可能会规定这一点。

于 2010-05-19T11:54:44.617 回答
1

我在货币金额方面做了一些(只是一点点),我对我公司使用的策略非常好奇......

事实证明,我们使用double,但他们已经考虑过了。

问题是我们处理的数量不是很大(比如少于 10k),我们最多需要小数点后 3 位,总共 7 位有效数字。

由于我们使用的是 64 位软件(和 C++),因此该double类型为我们进行的操作数量提供了足够的有效数字 :)

如果您需要更高的精度,可以使用一些算法(例如在添加多个货币时),但我个人认为问题的核心更多来自:

  • 从一种货币到另一种货币的转换,当然会不断变化
  • 印刷问题,有些钱不需要小数,有些最多需要 2,等等......

也许你可以扩展你正在做的操作?

于 2010-05-19T06:32:42.163 回答