求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
谈MongoDB Shell下的长整型截断问题
 
作者:Gian Maria Ricci   来源:CSDN   发布于 2016-6-13
 
MongoDB Shell下的长整型问题,是MongoDB臭名昭著的缺点。在这短暂的阅读中,Gian Maria Ricci(Linked in)将解释他是如何解决这一问题的。
在Mongo shell中简单的代码:
db.TestCollection.insert({"_id" : 1, "Value" : NumberLong(636002954392732556) })
db.TestCollection.find()

你想要在Mongo中插入一条记录,然后返回记录。记录被插入后返回值会令人大吃一惊。下面是从RoboMongo得到的输出:
{
 "_id" : 1.0,
 "Value" : NumberLong(636002954392732544)
}

属性“值”没有你插入的数字,数字似乎是舍入和一些精度的丢失,即使它是一个NumberLong型和一个完全有效的64位长整型636002954392732556。这种行为让我很吃惊,因为我希望舍入的只有double型,而不是一个Int64的长整型。
实际上,使用64位的双精度浮点数表示,不能拥有一个64位长整型相同的精度,因为64位的一部分用来存储一个指数。如果你试图用双精度浮点来表示一个像636002954392732556一大串数字,那么一些四舍五入将会发生。如果你不相信,试试这个在线转换器转换636002954392732556,这里是结果:

图片描述

图1:浮点数舍入

上面就是舍入带来的问题,因为有些数字转换为浮点数格式,即使我使用NumberLong bson扩展指定,我想要一个长整型而不是一个浮点类型。
这背后的原因很微妙,接着试另一个例子,在Mongo shell(RoboMongo环境)中只输入NumberLong型(636002954392732556),并验证结果。

图片描述

图2:NumberLong直接从shell中获取舍入

这揭示了一个错误,在数返回时,则用引号括起来了,这说明引用是有问题的。在JavaScript中,每一个数字都是double型,如果你写NumberLong型(636002954392732556)JavaScript 转化这个作为参数传递的数字 636002954392732556来调用NumberLong函数。由于在JavaScript中的每个数字是一个double型,636002954392732556这个数会舍入之前它传递给NumberLong函数。
如果你周围有引用的数字,在这种情况下,将一个字符串传递给NumberLong型,舍入并不会发生,以及NumberLong函数是完全有能力将字符串转换为一个数字。
在Mongo shell中,当你使用NumberLong型创建数字总是使用引号,实际上,这个错误只发生在非常大的数字中,但是你需要明白如果创建一个脚本,那么就需要使用NumberLong型。
 
分享到
 
 
 
 



利用Gitlab和Jenkins做CI
CPU深度学习推理部署优化
九种跨域方式实现原理
 
 讲座 设计模式C语言
 讲师:薛卫国
 时间:2019-4-20
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
希望我们的资料可以帮助你学习,也欢迎投稿&提建议给我
频道编辑:winner
邮       件:winner@uml.net.cn

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号