V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiangyuecn
V2EX  ›  程序员

后台 long 类型在 js 中丢失精度的问题大家是怎么解决的?

  •  
  •   xiangyuecn ·
    xiangyuecn · 2019-01-11 10:44:14 +08:00 · 7534 次点击
    这是一个创建于 1903 天前的主题,其中的信息可能已经有所发展或是发生改变。

    查了一下 JavaScript 能处理的最大整数为 Math.pow(2, 53) == 9007199254740992。9007199254740992+1 就开始不能正确表示了。

    后端数据中有些 long 类型的数据(比如 id 生成器生成的 long 类型 id ),如果直接发数字给前端,就会出问题。

    但一棍子打死全部 long 类型转成字符串好像也比较困难。想了一下,全转成字符串操作起来有点复杂,一不留神就会遗漏。而且因为 long 类型包含 int 类型范围,有可能因为测试值并未超过 js 的最大精度,漏转的地方会成为难以排查的隐藏 bug。

    v 友们遇到过这种问题吗,要怎样方便的解决?

    20 条回复    2019-11-23 20:32:06 +08:00
    shapl
        1
    shapl  
       2019-01-11 10:53:09 +08:00   ❤️ 1
    lzxz1234
        2
    lzxz1234  
       2019-01-11 11:07:02 +08:00
    一棍子打死全部 long 类型转成字符串好像也比较困难
    找对地方,一点也不困难
    wenzhoou
        3
    wenzhoou  
       2019-01-11 11:07:30 +08:00 via Android
    个人认为既然是 ID,你又不拿它做数字运算。那就应该定义成字符串类型。岂不妙哉。
    66beta
        4
    66beta  
       2019-01-11 11:09:14 +08:00 via Android
    同楼上,你是 ID,又不做运算,字符串有什么还担心的
    VDimos
        5
    VDimos  
       2019-01-11 11:15:52 +08:00 via Android
    用第三方库
    supuwoerc
        6
    supuwoerc  
       2019-01-11 11:17:13 +08:00
    不做运算直接 String 岂不妙哉
    xiangyuecn
        7
    xiangyuecn  
    OP
       2019-01-11 11:17:55 +08:00
    @66beta @wenzhoou
    我也是这样想的,ID 这种处理起来比较简单。但 long 类型并不只是 id 会用到啊。可能某些计算结果也是 long 类型,如果忘记处理成 string,不就出乱子了么,而且忘记处理的有点难排查,因为测试时这个 long 值可能比较小,测试时不会出问题,就埋了个雷。

    @lzxz1234 #2 这个地方难找,昨晚想了一晚上 还失眠了
    xiangyuecn
        8
    xiangyuecn  
    OP
       2019-01-11 11:20:30 +08:00
    @shapl 厉害了这个 js 库,拿来用了
    lzxz1234
        9
    lzxz1234  
       2019-01-11 11:23:26 +08:00   ❤️ 1
    你要把数据返给前端,肯定有个地方进行序列化吧,可能是模板可能是 json,在这定制个规则加上引号就行了
    wenzhoou
        10
    wenzhoou  
       2019-01-11 11:29:03 +08:00 via Android
    非 ID 的话。具体问题具体分析吧。

    a 系统和 b 系统的数值范围不一致,这很正常。前端到后台,后台到数据库和别的系统,数值不一致这种事情多了。

    你把前端的取值范围调大了。前端的数据往后台系统传的时候,也有可能越界啊。

    不过,你把后台系统的 long 型定为标准,原则上也是没有问题的。

    问题能解决就好。
    lolizeppelin
        11
    lolizeppelin  
       2019-01-11 11:33:02 +08:00   ❤️ 1
    用 jsonlint 加 long.js 解决

    这样 json 解析的时候 超过长度的会返回的就是一个 Long 对象

    数字处理会方便点...
    xiangyuecn
        12
    xiangyuecn  
    OP
       2019-01-11 11:41:24 +08:00
    @lzxz1234 嗯,json 数据 我研究一下是后端处理简单还是前端处理简单
    lolizeppelin
        13
    lolizeppelin  
       2019-01-11 11:43:18 +08:00
    随便看了下 1 楼的库, 就代码行数上来看太简单了很有可能 json 解析并不靠谱

    应该不如 jsonlint

    虽然我都没认真读过里面代码, 但是 jsonlint 原理上屌不少 23333
    brucewuio
        14
    brucewuio  
       2019-01-11 13:46:10 +08:00
    分开咯 比如 2 个 int 自己写个能满需求的
    zouqiang
        15
    zouqiang  
       2019-01-11 15:50:40 +08:00
    json 序列化的时候转 string
    DOLLOR
        16
    DOLLOR  
       2019-01-11 16:18:59 +08:00
    https://github.com/MikeMcl?tab=repositories
    这位仁兄写的几个 2K+Stars 工具都挺不错的,可以操作大数字,可以选一个试试。
    vigossliao
        17
    vigossliao  
       2019-01-11 17:27:47 +08:00
    这些工具库还是没有解决掉本质的问题

    而且忘记处理的有点难排查,因为测试时这个 long 值可能比较小,测试时不会出问题,就埋了个雷。


    某个字段可能出现 但是没有处理 或者 忘记处理了 或者 不知道那个字段会出现这个问题

    就算前端有各种工具库来处理都是无济于事
    除非前端在涉及到 number 的时候都用工具库来处理
    LeoEatle
        18
    LeoEatle  
       2019-01-11 22:53:26 +08:00
    先考虑这个数据是用作什么的,id 的话完全可以转字符串
    zzjas98
        19
    zzjas98  
       2019-01-12 03:56:49 +08:00
    最近 Chrome 出了一个对 BigInt 的 type 的支持。是作为浏览器内的 primitive type 支持的,应该效果不错。但是跨浏览器原生支持好像还不是很全。

    > BigInts are a new numeric primitive in JavaScript that can represent integers with arbitrary precision.

    想了解的话可以看看这些链接
    Spec: https://tc39.github.io/proposal-bigint/
    Coverage: https://caniuse.com/#search=bigint
    Chrome Implementation: https://developers.google.com/web/updates/2018/05/bigint

    总而言之是个挺新的东西,不一定现在有用,但是楼主不妨了解一下没准过段时间就能广泛使用了。
    q540374501
        20
    q540374501  
       2019-11-23 20:32:06 +08:00
    bigint 没用啊,我要把 objectId 当做 bitmap 来用,加个 n,redis 根本不认识我靠
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1400 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 17:31 · PVG 01:31 · LAX 10:31 · JFK 13:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.