2012-03-29 10 views
1

Ich bin neu in MongoDB und versuche einige Grundlagen, aber das erstaunte mich. Ich vermute, ich verstehe ein Kernkonzept falsch, aber kann mir jemand sagen, was hier vor sich geht?Doppelter Rundungsfehler in MongoDB mit Group()

Mit dem offiziellen MongoDB C# -Laufwerk habe ich 10.0000 dieser Dokumente in eine db-Sammlung namens "lots" eingefügt.

  // 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)); 

      ... 

Ich habe versucht, dies in der Schale, weil ich nicht glauben, was ich in dem C# Fahrer war zu sehen, aber das Ergebnis ist das gleiche;

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

mich korrigieren, wenn ich falsch bin, aber sollte nicht 29.99 * 10000 == ?

Antwort

3

Korrigieren Sie mich, wenn ich falsch liege, aber nicht 29,99 * 10000 == 299900 sollte?

Ihre Daten enthielten nicht 29.99. Schau mal hier:

const double price = 29.99; 

Die price gleich den double Wert setzt die am nächsten-29,99 ist. Das ist nicht 29.99. Um genau zu sein, ist Ihr Wert 29.989999999999998436805981327779591083526611328125.

Dies ist nur tangential mit Mongo zu tun - es ist grundlegend für die Verwendung von binären Fließkommazahl. Wenn Mongo decimal unterstützt, sollten Sie das stattdessen für alle finanziellen Werte verwenden. Ich kann nicht siehe alles wie BsonDecimal was ist, was ich erwartet hätte - wenn Sie das nicht tun können, möchten Sie vielleicht Ihre Werte als skalierte ganze Zahlen statt - z. Speichern der Anzahl von Cent anstelle der Anzahl von Dollars.

Siehe meine Artikel auf binary floating point und decimal floating point für weitere Informationen.

+0

Nein. Ich glaube nicht, dass Mongo Dezimal unterstützt. Ich dachte, es wäre etwas Grundlegendes. Wenn ich das Double in C# berechne, ist es in Ordnung, also war ich überrascht, etwas nicht zu sehen, was ich nicht erwartet hatte. Ich hatte schon überlegt, Ganzzahlen zu verwenden, weil ich einige der Dinge gelesen hatte, aber ich war neugierig, warum, als Mongo eine Zahl mit einem Dezimalpunkt darin zu akzeptieren schien. Danke John! – cirrus