gpt4 book ai didi

MongoDB 的 NumberLong 只有 54 位签名?

转载 作者:可可西里 更新时间:2023-11-01 09:46:58 27 4
gpt4 key购买 nike

MongoDB 的 NumberLong 真的是 64 位有符号整数吗?

据说 MongoDB 的 NumberLong 是一个 64 位有符号整数,这意味着我们可以使用 -2^63 <= x <= 2^63-1,其中 x 是一个 NumberLong。但是,从 NumberLong(x) 中加 1 或减 1 不会返回 x <= -2^54 或 x >= 2^54 的预期值,但会返回 -2^53 <= x <= 的正确值2^53.
因此,可靠的 NumberLong 数字似乎是 54 位有符号整数。

这是为什么?
我做错了什么吗?

来自 mongo shell 的示例:

> NumberLong( Math.pow(2,54) )
NumberLong("18014398509481984") // Expected
> NumberLong( Math.pow(2,54)-1 )
NumberLong("18014398509481984") // **NOT** Expected
> NumberLong( -Math.pow(2,54) )
NumberLong("-18014398509481984") // Expected
> NumberLong( -Math.pow(2,54)+1 )
NumberLong("-18014398509481984") // **NOT** Expected

> NumberLong( Math.pow(2,53) )
NumberLong("9007199254740992") // Expected
> NumberLong( Math.pow(2,53)-1 )
NumberLong("9007199254740991") // Expected
> NumberLong( -Math.pow(2,53) )
NumberLong("-9007199254740992") // Expected
> NumberLong( -Math.pow(2,53)+1 )
NumberLong("-9007199254740991") // Expected

使用 MongoDB 2.0.0

最佳答案

哇,这真令人费解。显然这里发生了某种舍入错误。

> NumberLong("18014398509481984")-NumberLong("1");
18014398509481984

> NumberLong("18014398509481984")-NumberLong("2");
18014398509481982

> NumberLong("18014398509481984")+NumberLong("1");
18014398509481984

> NumberLong("18014398509481984")+NumberLong("2");
18014398509481984

> NumberLong("18014398509481984")+NumberLong("3");
18014398509481988

这可能是运行 shell 的 JavaScript 引擎有问题,而不是 MongoDB 本身。看看这个,例如——$inc 工作正常:

> db.test.insert({twoTo54:NumberLong("18014398509481984")});
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481985") }
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481986") }
> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : NumberLong("18014398509481987") }

但你必须要小心。如果您只使用普通文字 1,它会将类型转换为数字,然后打破 $inc:

> db.test.update({},{$inc:{twoTo54:1}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }
> db.test.update({},{$inc:{twoTo54:1}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }

即使您使用 NumberLong("1") 返回到 $inc,它仍然是错误的:

> db.test.update({},{$inc:{twoTo54:NumberLong("1")}});
> db.test.find();
{ "_id" : ObjectId("4f204847756aa806028abce1"), "twoTo54" : 18014398509481988 }

记住这一点绝对好。

关于MongoDB 的 NumberLong 只有 54 位签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7777514/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com