[SERVER-7812] NumberLong(max_of_int64) returns wrong result in mongo shell Created: 30/Nov/12  Updated: 26/Oct/21  Resolved: 26/Oct/21

Status: Closed
Project: Core Server
Component/s: Shell
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Vadim Voitsiakh Assignee: Geert Bosch
Resolution: Done Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux 3.5.0-18-generic #29-Ubuntu SMP x86_64
MongoDB 2.2.2


Issue Links:
Related
is related to SERVER-10966 Passing a Float to constructors of Nu... Backlog
is related to SERVER-24802 Database store a value different to t... Closed
Operating System: ALL
Steps To Reproduce:

1. Open Mongo shell.
2. Type: NumberLong(9223372036854775807).
3. If you got answer: NumberLong(9223372036854775807) close shell and go to step 1.
4. More frequently you'll get answer: NumberLong("-9223372036854775808"). I think this is wrong.
My example:
MongoDB shell version: 2.2.2
connecting to: dataproviders
> NumberLong(9223372036854775807)
NumberLong("-9223372036854775808")

Participants:

 Description   

Assume that max value of 64-bit integer id 2^63-1 = 9223372036854775807
But sometimes in mongo shell we got wrong results from NumberLong(9223372036854775807):

MongoDB shell version: 2.2.2
connecting to: dataproviders
> NumberLong(9223372036854775807)
NumberLong("-9223372036854775808")



 Comments   
Comment by Geert Bosch [ 26/Oct/21 ]

The observed behavior is a consequence of passing a double precision floating point number.

Comment by Hiroaki [ 02/May/13 ]

I'm doubting that this issue is the problem of cast to floating point in somewhere in the way to the results.
Because the NumberLong overflows in tightly 53bit.

> db.test.save({i:NumberLong(0x20000000000001)})
> db.test.find({},{_id:0})
{ "i" : NumberLong("9007199254740992") }
// It must be 9007199254740993 

Comment by Tad Marshall [ 30/Nov/12 ]

The sign reversal is interesting and may be our bug. But I think that the loss of precision is because JavaScript's native numeric format is floating point.

> NumberLong(9223372036854775807) // unquoted number is interpreted as negative
NumberLong("-9223372036854775808")
> NumberLong("9223372036854775807") // quoted number echoes as itself
NumberLong("9223372036854775807")
> NumberLong(9223372036854775807) + 0 // JavaScript has rounded the number
-9223372036854776000
> NumberLong("9223372036854775807") + 0 // quoted version is rounded, but no sign reversal
9223372036854776000

The number that JavaScript rounds off to overflows 63 bits (i.e. into the sign bit), which may be where the sign reversal is coming from.

9223372036854775807 is 0x7FFFFFFF'FFFFFFFF.
9223372036854776000 is 0x80000000'000000C0 (if I calculated it right).

Comment by Vadim Voitsiakh [ 30/Nov/12 ]

It is more likely javascript's problem:

> 9223372036854775807
9223372036854776000

Generated at Thu Feb 08 03:15:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.