数学运算后mongoDB奇怪的结果

I have an e-commerce site with digital products (no inventory, only reporting features).

And sometimes i get weird results with customers account balances:

e.g. customer has 30 on his balance and after purchasing a product for 29.95 i see in admin panel that his balance is 0.050000000000001 not 0.05 as expected.

Or sometimes i see 520.949999999999 instead of 520.95.

Why is this happening?

Site runs on PHP and interacts with mongo though YiiMongoDbSuite

Using double or floats is not advisable for any sort of currency math where precise calculations are vital. This question goes into great detail on the subject. A better alternative would be to track these values with integers, where 1 is the smallest unit of currency (cent in this case), and work from there.

Depending on how you do the math on floating points (saving exact values, the result of subtraction, or using the $inc operator), you're likely to end up with mixed results:

> 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 }

If you're set on using floating points and doing the math in PHP (i.e. not using $inc in the update query), consider using round() with a set precision, which should yield results similar to the first example above. number_format() is fine for display, but be careful not to use it when updating the document, since it returns a string.