2016-04-21 36 views
2

打交道时,我有发票表中的三个字段处理精度:如何使用货币在MySQL和PHP

subtotal decimal(12,4) 
tax_amount decimal(12,4) 
total  decimal(12,4) 

我遇到了与舍入的问题。所以有以下价值的发票。这个增加加起来,但是当显示发票数据并生成发票的pdf时,显示的数据并不总是加起来。

  stored value  displayed (rounded) 
           value 
subtotal 165.1610   165.16 
tax_amount 24.7742   24.77 
total  189.9352   189.94 

存储的值加起来。通过在PHP中添加subtotaltax_amount值来计算total列。四舍五入正确完成,但165.16 + 24.77 = 189.93和NOT 189.94。

我该如何处理这些情况?这并非总是如此。

+1

欢迎来到浮点数的乐趣。您无法直接解决问题。绕过它。将您的现金价值存储为便士,而不是分数美元。 '(16516 + 2477)/ 100'最终会更好。 –

+1

@MarcB你真的认为这是一个浮动数字问题吗?它甚至会发生整数值。问题是存储所有3个三个值。他应该通过向tax_amount添加小计来计算总计。数据库未规范化,因为total是小计和tax_amount的功能依赖项。 https://en.wikipedia.org/wiki/Functional_dependency – steven

+0

@steven我没有规范化表格,因为我想避免每次需要添加值时都需要显示它们。这将允许某人添加4个小数点的值,然后将结果放在一个地方,但另一名开发人员可以在添加之前舍入,从而得出不同的结果。该表格是打印出来的发票的记录,因此它必须存储每次给予客户的实际价值。 – Vic

回答

2

将存储的值舍入到最近的一分钱。当您使用PHP计算总计或小计时,请总结四舍五入的值。

如果您打算以某种方式显示舍入集合,最好的做法是以完全相同的方式计算以避免混淆。

可能将聚合项目显示为未被舍入,然后舍入最后的总和用于显示目的。如果您在数据库中存储小数点便士,从长远角度看,这可能会更好地发挥作用。

另一种选择可能是对发票进行四舍五入以解决差异,但这可能会让一些人感到困惑。

这就是说,从编程角度来说,最好是尽可能避免分数便士。

无论你选择做什么,保持一致!

+0

因为我读了[本文](https://rietta.com/blog/2012/03/03/best-data-types-for-currencymoney-in/),所以我存储了4个小数点,以符合[公认会计原则](http://www.fasab.gov/authoritative-source-of-gaap/)。尽管如此,我仍然怀疑。 – Vic

+0

小数点后4位的原因是因为任何舍入错误往往会超过数千个事务。这并不意味着你完全免疫了发票0.01美元左右;您仍然必须在发生这些差异时以一致的方式解决这些差异。 –