Domanda

I'm new to MongoDB and trying out some fundamentals, but this astonished me. I'm guessing I misunderstand some core concept, but can anyone tell me what's going on here?

Using the official MongoDB C# drive, I've inserted 10,0000 of these docs into a db collection called 'lots'.

         // Insert some test data
         const double price = 29.99;
         var bsonDoc = new BsonDocument { 
            {"glossary", new BsonDocument {
                    {"title", "example glossary"},
                    {"GlossDiv", new BsonDocument {
                        {"title", "S"},
                        {"price", new BsonDouble(price)},
                ...
                /* full doc chunk removed here for brevity */
                ...
            };
            ...
                         const int numObjects = 10000;
         for (int i = 0; i < numObjects; i++)
             col.Insert(new BsonDocument(bsonDoc));

            ...

I tried this in the shell because I didn't believe what I was seeing in the C# driver, but the result is the same;

db.lots.group({key:{"glossary.GlossDiv.title":true}, reduce:function(obj,out){out.total+=obj.glossary.GlossDiv.price;}, initial:{total:0} }) [ { "glossary.GlossDiv.title" : "S", "total" : 299899.99999995757 } ]

Correct me if I'm wrong but shouldn't 29.99*10000 == 299900 ?

È stato utile?

Soluzione

Correct me if I'm wrong but shouldn't 29.99*10000 == 299900 ?

Your data didn't contain 29.99. Look here:

const double price = 29.99;

That sets price equal to the double value which is closest to 29.99. That's not 29.99. To be exact, your value is 29.989999999999998436805981327779591083526611328125.

This is only tangentially to do with Mongo - it's fundamental to using binary floating point. If Mongo supports decimal, you should use that for any financial values instead. I can't see anything like BsonDecimal which is what I'd have expected - if you can't do that, you may well want to store your values as scaled integers instead - e.g. storing the number of cents instead of the number of dollars.

See my articles on binary floating point and decimal floating point for more information.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top