天天看点

浏览器JSON的插件(JSON-handle)使用问题

问题描述

对于json的数据如果不编排一下格式查看起来很费劲,比较流行的一款chrome/Firfox下处理json的插件JSON-handle。最近使用的时候发现一个问题,导致格式化后根据订单去页面中定位数据时查询不到,非常诡异。回想起前一段时间做功能的时候,在js中显示订单号时也出现过类似的问题,于是决定一探究竟。探究到最后发现是由于js中number的精度问题导致的。我在js中展示的时候由于数据类型是long,超过了js的精度,我就在后台多加了一个String类型的字段专门用来js展示订单号之用,这样解决了我的问题。详细原因,请看问题原因描述详解

参考文章:

http://www.heyuan110.com/2015/06/16/Chrome-FireFox%E5%A4%84%E7%90%86JSON%E7%9A%84%E6%8F%92%E4%BB%B6/

插件官网:

jsonhandle.sinaapp.com

问题原因描述详解

地址:

TB”>http://zhidao.baidu.com/link?url=vVCdzXTs5kTKykFkPuxdfcpS7umlMPejIBudaU9U51Us5SmMkc4aYQm4gGMj3dclM0IRnBzBAQFLdE6_tsKuAfiPDK_9Wg1XWtT8ri-TB

摘录:

JavaScript 中的数字是用”IEEE 754 双精度64 位浮点数”来存储的,

其格式为:

s x m x 2^e
           

s 是符号位,表示正负。

m 是尾数,有 52 bits.

e 是指数,有 11 bits.

在 ECMAScript 规范 里有给出 e 的范围为 [-1074, 971].

Number.MAX_VALUE = 1 x (2^53 - 1) x 2^971 = 1.7976931348623157e+308

Number.MIN_VALUE = 1 x 1 x 2^(-1074) = 5e-324

//使用如下js查看Number.MAX_VALU与Number.MIN_VALUE
alert(Number.MAX_VALUE);
alert(Number.MIN_VALUE);
           

所以JS能存储的数值是非常大的。

但是使用如下测试语句:

var x = Math.pow(, ) - ;
while (x != x + ) x++;
alert(x);
           

结果看似死循环的程序,跳出了,x的最终结果为9007199254740992=2^53。

也就是说,

当 x 小于等于 2^53 时,可以确保 x 的精度不会丢失,

当 x 大于 2^53 时,x 的精度有可能会丢失。

//x 为 ^ +  时,其二进制表示为:
... (中间共有  个 )
//用<a href="https://www.baidu.com/s?wd=%E5%8F%8C%E7%B2%BE%E5%BA%A6%E6%B5%AE%E7%82%B9%E6%95%B0&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3nHu9rAFWP1I9mhFBPHN90ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1DknH0YPjfLPWcdnW0znHTvPHb" target="_blank" class="baidu-highlight">双精度浮点数</a>存储时:
e = 1; m = 10000..00(共 52 个 0,其中 1 是 hidden bit)
           

显然,这和 2^53 的存储是一样的。

按照上面的思路可以推出,

对于 2^53 + 2, 其二进制为 100000…0010(中间 51 个 0),也是可以精确存储的。

最后结论:

当 x 大于 2^53 且二进制有效位数大于 53 位时,就会存在精度丢失。

最后建议

个人还是感觉sublime比较好用,使用里面的Pretty JSON插件还是挺好用的。