0

我有一个包含数字产品的电子商务网站(没有库存,只有报告功能)。

有时我会在客户账户余额中得到奇怪的结果:

例如,客户的余额为 30,在以 29.95 的价格购买产品后,我在管理面板中看到他的余额与预期0.050000000000001不符。0.05

或者有时我看到520.949999999999而不是520.95.

为什么会这样?

站点在 PHP 上运行并通过YiiMongoDbSuite与 mongo交互

4

1 回答 1

0

对于精确计算至关重要的任何类型的货币数学,不建议使用双精度或浮点数。这个问题非常详细地讨论了这个主题。一个更好的选择是用整数来跟踪这些值,其中1是最小的货币单位(在这种情况下是美分),然后从那里开始工作。

根据您对浮点数进行数学运算的方式(保存精确值、减法结果或使用$inc运算符),您最终可能会得到混合结果:

> db.foo.insert({ _id: 'value', x: 0.05 })
> db.foo.insert({ _id: 'subtraction', x: 30 - 29.95 })
> db.foo.insert({ _id: 'decrement',  x: 30 })
> db.foo.update({ _id: 'decrement' }, { $inc: { x: -29.95 }})
> db.foo.find()
{ "_id" : "value", "x" : 0.05 }
{ "_id" : "subtraction", "x" : 0.05000000000000071 }
{ "_id" : "decrement", "x" : 0.05000000000000071 }

如果您打算使用浮点数并在 PHP 中进行数学运算(即不在$inc更新查询中使用),请考虑使用具有设定精度的round(),这应该会产生类似于上面第一个示例的结果。number_format() 可以很好地显示,但请注意在更新文档时不要使用它,因为它返回一个字符串。

于 2013-06-27T15:59:53.720 回答