2012-03-29 2 views
1

MongoDB를 처음 사용하면서 몇 가지 기본 사항을 시험해 보았습니다. 그러나 놀랐습니다. 내가 몇 가지 핵심 개념을 오해 한 것 같지만 아무도 나에게 무슨 일이 일어나는지 말해 줄 수 있니?Group()이있는 MongoDB의 이중 반올림 오류

공식 MongoDB C# 드라이브를 사용하여 10,0000 개의 이러한 문서를 '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)); 

      ... 

나는 C# 드라이버에서 무엇을 보았는지 믿지 않았기 때문에 쉘에서 이것을 시도했지만 결과는 동일합니다.

db.lots.group ({키 { "glossary.GlossDiv.title"TRUE} 감소 : 함수 (OBJ 아웃) {out.total + = obj.glossary.GlossDiv.price}, 초기 : {총 : 0}}) [{ "glossary.GlossDiv.title": "S", "총"299899.99999995757}] 내가 틀렸다하지만 경우

나를 수정은 안 29.99 * 10000 == ?

답변

3

내가 틀렸다면 정정하되 29.99 * 10000 == 299900이 아니어야합니까?

데이터에 29.99가 없습니다. 여기 봐 : 29.99-가장 가까운double 값과 동일한 price을 설정

const double price = 29.99; 

합니다. 그것은 이 아니며 29.99가 아닙니다. 정확히 말하면 값은 29.989999999999998436805981327779591083526611328125입니다.

이것은 단지 Mongo와 관련이 있습니다 - 이진 부동 소수점을 사용하는 것이 기본입니다. Mongo가 decimal을 지원하는 경우, 재정 값 대신 Mongo를 사용해야합니다. 나는 과 같이 표시 할 수 없습니다. 내가 기대했던 것입니다. 만약 그렇게 할 수 없다면, 스케일 된 정수로 값을 저장하는 것이 좋습니다. 달러 수 대신 센트 수를 저장합니다.

자세한 내용은 binary floating pointdecimal floating point에 대한 내 기사를 참조하십시오.

+0

아니요. 나는 몽고가 십진수를지지한다고 생각하지 않는다. 나는 그것이 뭔가 근본적이라고 생각했다. C#에서 double을 계산하면 괜찮습니까. 그래서 기대하지 않은 것을 보지 않아서 놀랐습니다. 나는 이미 읽었던 것들 때문에 정수 사용을 고려하고 있었지만 Mongo가 그 안에 소수점이있는 숫자를 받아들이는 것처럼 보였던 이유를 알고 싶다. 감사합니다 존! – cirrus