JS 大数溢出问题

2023-10-18 10:21:24 +08:00
 justdoit123
后端的大数到 JS 端 JSON.parse 之后,经常大数溢出。

这个问题之前一直是在后端看到一处,就 stringify 一处。现在实在是觉得烦了,想请教下各位有什么更好的做法?

查了些资料,这个溢出是在 JS 进程里 JSON.parse 的时候发生的,跟 JS 自身有关系,跟 JSON 没有关系。想着,在 JSON.parse 的时候,换成 BigInt 的 JSON.parse 。但是这其中也有两种策略:

1. 只要是整数,全部转成 BigInt ,不管实际会不会溢出。这样的好处是统一,坏处怕会有什么性能问题
2. 只有当一个整数会溢出的时候,才会转成 BigInt 。但是这样用的时候还需要做下判断,比较麻烦。

暂时想在内部后台系统里尝试下,浏览器兼容不成问题。有没有别的高招?

PS. 这个真是 JS 的天坑。
3800 次点击
所在节点    JavaScript
47 条回复
nianyu
2023-10-18 16:13:27 +08:00
@cmdOptionKana 大兄弟秀优越也讲个基本法,当个谜语人,又讲不出什么东西。 淘宝订单都是先转字符串在处理的,这都是业界常识,跟基础知识有半毛钱关系?
palytoxin
2023-10-18 17:19:06 +08:00
不要折腾 int,就用 string
IvanLi127
2023-10-18 17:26:56 +08:00
遇到大数不是第一时间用字符串或者自定义的格式传么?这要是天坑的话……那以后的路得多难走。
BurNIng1988
2023-10-18 18:02:22 +08:00
你如果在 v8 环境执行这个代码,就只能乖乖转字符串,如果后端不要字符串就走非 node 的 bff 再转一次
qeqv
2023-10-18 18:38:23 +08:00
以前我是后端自己实现了一个 stringify 解决这种不同 JSON 解析器出现的奇怪问题的 - -
justdoit123
2023-10-18 18:55:45 +08:00
另外,纠正一下,溢出的是 JS Runtime ,不是 JSON 。在你把一个 int64 转成 JSON 格式的时候,它并没有“失真”,可以在其它支持 int64 的语言里试试。

之前看 Twitter 的前端代码的时候,偶然发现他们有 `id_str` 这样的字段,今天翻了下文档,果然是为了处理大数溢出问题。https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/object-model/tweet
YuJianrong
2023-10-19 12:28:58 +08:00
@justdoit123 这其实是历史问题。
当 Douglas Crockford 发明 JSON 的时候,其实只是为了 Javascript 方便用,就直接借用了 Javascript 定义 Object 的方式来制定 JSON 标准(所以 JSON 全称是 JavaScript Object Notation )。但他懒到根本没有按 Javascript 的 number 来定义 JSON 的 number 类型,JSON 的 number 在标准上并没有任何限制。在你的场景下你觉得 int64 的 JSON 数字在 JS 读不出正确精度是 bug ,但同样别的 app 也可以写一个 BigDecimal 转出来超过 int64 的大数,你的 app 同样不能正确读出来,也是 bug 。

所以为了互操作性,不管在什么环境下 JSON 遇到数字的时候都应该当作 double 来处理,这样最不容易产生问题。

ref: https://en.wikipedia.org/wiki/JSON -> interoperability

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/983013

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX