MongoDB中带组()的双舍入错误

MongoDB中带组()的双舍入错误,mongodb,double,rounding-error,Mongodb,Double,Rounding Error,我是MongoDB的新手,正在尝试一些基础知识,但这让我很惊讶。我猜我误解了一些核心概念,但谁能告诉我这里发生了什么 使用官方的MongoDB C#drive,我将100000个这样的文档插入到一个名为“lots”的db集合中 // Insert some test data const double price = 29.99; var bsonDoc = new BsonDocument { {"glossary

我是MongoDB的新手,正在尝试一些基础知识,但这让我很惊讶。我猜我误解了一些核心概念,但谁能告诉我这里发生了什么

使用官方的MongoDB C#drive,我将100000个这样的文档插入到一个名为“lots”的db集合中

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

            ...
//插入一些测试数据
常数双倍价格=29.99;
var bsonDoc=新的BsonDocument{
{“词汇表”,新的B文档{
{“标题”,“示例词汇表”},
{“GlossDiv”,新的B文件{
{“标题”,“S”},
{“价格”,新BsonDouble(价格)},
...
/*为简洁起见,此处删除了完整的文档块*/
...
};
...
常量int numObjects=10000;
for(int i=0;i
我在shell中尝试了这个,因为我不相信我在C#driver中看到的,但结果是一样的

db.lots.group({key:{“glossary.GlossDiv.title”:true},reduce:function(obj,out){out.total+=obj.GlossDiv.price;},首字母:{total:0}) [{“glossary.GlossDiv.title”:“S”,“total”:299899.999999 5757]

如果我错了,请纠正我,但不应该是29.99*10000==299900

如果我错了,请纠正我,但不应该是29.99*10000==299900

您的数据不包含29.99。请查看此处:

const double price = 29.99;
这将
price
设置为最接近29.99的
double
值。这不是29.99。准确地说,您的值是29.98999999998436805981327779591083526611328125

这与Mongo的关系不大——它是使用二进制浮点的基础。如果Mongo支持
十进制
,那么您应该将其用于任何财务值。我看不到任何类似于
BsonDecimal
的东西,这正是我所期望的——如果您不能做到这一点,您可能需要按比例存储您的值而不是tegers-例如,存储美分数而不是美元数


有关更多信息,请参阅我在和上的文章。

不。我不相信Mongo支持十进制。我认为这是一个基本的问题。如果我在C#中计算双精度,这很好,因此我很惊讶没有看到我意想不到的东西。我已经考虑使用整数,因为我读过一些东西,但我很好奇知道为什么当Mongo似乎接受一个带小数点的数字时。谢谢John!