自动主键在JS精度丢失中的坑

一、场景描述


 

    发现js把response中的数据转成json格式之后,值不一样了。
    原因:在js中Number类型统一按浮点类型处理,大整数的精度丢失和浮点数本质上是一样的,尾数位最大是 52 位,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即 9007199254740992,大于 9007199254740992 的可能会丢失精度。

解决:后台把Long转成string在返回给前段。

二、浮点数简介

    对于浮点类型的数据采用单精度类型(float)和双精度类型(double),按照浮点数存储标准(IEEE 制定)来存储,float数据占用32bit,double数据占用64bit。

    单精度的存储方式如下图所示:


    双精度的存储方式如下图所示:


三、浮点数转二进制
      例如:9.2转二进制
      整数部分:9 ==> 1001
      小数部分转二进制:小数乘以2,取整,小数部分继续乘以2,取整,得到小数部分0为止,将整数顺序排列.
      比如0.2
          0.2 * 2 = 0.4,取整0,小数部分0.4
          0.4 * 2 = 0.8,取整0,小数部分0.8
          0.8 * 2 = 1.6,取整1,小数部分0.6
          0.6 * 2 = 1.2,取整1,小数部分0.2
          ….无限循环
      即为0011*N

四、浮点数的二进制存储

        • 符号位:0表示正数,1表示负数.
        • 对于指数部分N,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127~128,所以可以对他进行置偏,根据浮点数的存储标注(IEEE),float 类型的指数起始数为127(二进制0111 1111),double类型的指数起始数为1023(二进制011 1111 1111),在此基础上加指数,得到的就是内存中的指数的表示形式.所以指数部分的存储采用移位存储,存储的数据为32位则元数据+127 ,64位则+1023
        • 尾数则直接填入,位数不够则补0,位数过多则0舍1入

    举个栗子:9.125
    整数部分:9.125==>9==>1001
    小数部分:
        0.125 * 2 = 0.25 ==> 取整0,余数0.25 ==>0
        0.25 * 2 = 0.5 ==> 取整0,余数0.5 ==>0
        0.5*2 = 1.0 ==> 取整1 ==>1
    拼接后9.125 ==> 1001.001==> 1.001001*2^3
    1.001001 * 2^3 ==>
    0 127 +3 0010 01 ==>
    0 1000 0010 0010 01 ==> 0100 0001 0001 0010 0000000000000000


五、浮点数精度丢失
    2.2转换成二进制为0 0111 1110 00110011001100110011 ….无穷,但是因为 float 和 double 存储的位数都有限,那么超出位数部分的肯定就被截断了。
    这就导致2.2最终被保留下来的可能就是:
    0 (1位符号位) 0111 1110(8位指数位) 00110011001100110011…(23位位数)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值