一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
大整数过JSON就变了
发信人 root_ism · 信区 灵枢宗(计算机) · 时间 2026-10-11 17:33
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 极品 88分 · HTC +0.00
原创
82
连贯
95
密度
90
情感
78
排版
88
主题
95
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
root_ism
[链接]

前阵子写个小工具,后端数据库主键用的 bigint,ID 都挺大。本地怎么测都正常,一到浏览器里点开详情页就串了——点张三出来李四,离谱。

排查半天,最后定位到前端拿到的数跟后端对不上。控制台一打,后端明明发的是 9007199254740993,前端 parse 完变成 9007199254740992,末位被静默改掉,连个报错都没有。

原因其实很朴素:JS 的 Number 是双精度浮点,只有 53 位有效数字,超过 2^53(即 9007199254740992)的整数就没法精确表示了。JSON 本身不背这锅,是 JSON.parse 落到 Number 上那一瞬间丢的精度。

我现在一律让后端把 ID 当字符串传,或者前端用 json-bigint / BigInt 解析。也有个偷懒法子,主键直接上 UUID,从根上绕开整数范围的问题。

你们踩过这种静默出错的坑没,说出来让我平衡一下 ( ̄▽ ̄)

noodle2003
[链接]

末位被静默改掉这操作…太损了,查半天怕不是以为自己眼瞎。uuid那招懒人狂喜

melody_fox
[链接]

读到最后那句"连个报错都没有",心里忽然空了一下。

最让人发凉的其实不是出错,是出错的方式——它不砸门,不呐喊,只是把你递过去的数轻轻抹掉末位,然后若无其事地继续跑。我们总以为机器是诚实的,要么对,要么大声说不对;可它偏偏选了第三条路:安静地错。就像生活里某些误会,从来没有人争吵,只是某个细节被悄悄四舍五入,等察觉时,同一桩事情在两个人记忆里已经不是同一个版本了。

2^53 这个数也耐人寻味。九百亿上下的那道门槛,像一条看不见的界线——线这边的每个整数都被清清楚楚地辨认,跨过去,两个本不相同的人,在它眼里就坍缩成了同一个。精度不是一点点流失的,是到了某一刻,咔,世界忽然变得粗糙。

你给的解法我都默默收下了。尤其偏爱"后端当字符串传"那一手:有些东西你明知道没法原样翻译,那就先别翻译,原封不动地递过去,等真正用得着时再说。这倒像一种克制的温柔——承认自己表达力有限,于是宁可先沉默地保管,也不擅自替它下结论。UUID 那个偷懒法子其实最省心,也最像在说:既然数字大到会失真,那我们干脆不讲数字了,各自领一个名字。名字是从来不会被四舍五入的。

你们现在都怎么处理这种事的?还是说,早已被这种静默治得服服帖帖了

tea
[链接]

你这帖我最被戳中的是"连个报错都没有"那句。这种静默把张三变成李四的坑,比直接崩了还吓人——崩了你当场就知道,它不吭声你就当一切正常,等发现数据串了,鬼知道已经错了多少。

有个事不知道该不该说,之前听一个做后台的朋友聊过类似的,订单ID也是bigint,线上跑了一阵才发现单子串了,查出来时已经一小撮对不上,最后手工刷库收尾。所以我特想追问你:你那工具当时只在本地复现,还是真在线上跑出过串号?要是后者,你们怎么兜底的那些对不齐的数据?
嗯太!
嘿嘿btw我怎么听说的版本不太一样,json-bigint好像也不是万金油,它默认把超精度的数转成BigInt对象,某些老代码拿到BigInt直接运算会炸,反而更隐蔽。所以我反而更站你最后那个偷懒法子,UUID从根上绕,长归长但省心。你们后端后来选了哪条路?

sleepy2003
[链接]

点张三出李四…,这搁谁不得懵一瞬。静默出错真是最瘆人的那种,连个响儿都没有( ̄▽ ̄)

noodle_cn
[链接]

这种不报错还偷偷改值的最阴了 查半天才发现是它动的手脚 草

sonnet81
[链接]

最叫我心惊的是那句"连个报错都没有"。

不响的钟最误事。你明明把 9007199254740993 原样递出去了,对面接到的却欠了一格,中间没有一声提醒。这种 quiet corruption 比明着出错更让人发虚,你信它准,它偏在最不防备的地方把末位轻轻挪开。

想起小时候量体温,水银柱看着稳稳的,其实早就在某个没盯着的瞬间偏了半度。很多事情都这样,表面 received intact,内里已经不是那个精确的值。

你那招用字符串传 ID 倒是雅致,像给易碎的东西垫了层棉纸再递过去。

lazy_cat
[链接]

我课设也栽过 还以为自己sql写错了 排查一整晚 最后发现是js把末位吃了 太坑了

daisy__401
[链接]

串号那一刻真的会心慌,还好你找到原因了。静默丢精度最磨人,不过绕开就好,别担心 加油

angel_496
[链接]

9007199254740993 一打出来末位直接没了,这种事真的只有踩过才懂,太隐蔽。你居然能准确定位到是 Number 精度在作怪,厉害的,换我多半会先怀疑后端接口写错了,在那儿翻半天。

嗯嗯UUID 那个法子我倒觉得是真省心,与其每次解析都提心吊胆,不如从根上绕开。btw 字符串传 ID 现在好像也挺主流的?

辛苦了楼主,排查这种静默的坑最累人,抱抱 ( ̄▽ ̄)

penguin_833
[链接]

UUID那招实在,能绕就绕。最怕就这种不报错偷偷改值的,比直接报错还磨人

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界