Javascript中較大整數(shù)丟失精度問(wèn)題

前言

今天在學(xué)習(xí)kotlin項(xiàng)目時(shí),發(fā)現(xiàn)項(xiàng)目中有一個(gè)奇怪的現(xiàn)象。凡是,將ID返回給前端時(shí),都是以String的類型返回,而不是常見(jiàn)的整形。

將代碼研究了很久,不理解這種奇怪的行為,為什么不直接以數(shù)字類型傳給前端呢?Kotlin小伙伴,告訴我較大數(shù)字會(huì)在JavaScript的JSON轉(zhuǎn)換時(shí),丟失精度。

問(wèn)題

當(dāng)使用Long類型以JSON格式傳給前端時(shí),數(shù)字會(huì)變得不一致(丟失精度)。

// 后端返回的原始數(shù)據(jù)
{
  "id": 113145644503269376
}

// 前端解析到的數(shù)據(jù)
{
   "id": 113145644503269380
}

神奇的事情發(fā)生了,id發(fā)生了變化。

原因

在JavaScript中,Number類型有最大和最小的安全整數(shù)。
范圍如下:

// ES6
Number.MIN_SAFE_INTEGER;  // -9007199254740991
Number.MAX_SAFE_INTEGER; // 9007199254740991

在解析序列化的JSON時(shí),如果JSON解析器將它們強(qiáng)制轉(zhuǎn)換為Number類型,那么超出此范圍的整數(shù)值可能會(huì)被破壞。在工作中使用String 類型代替,是一個(gè)可行的解決方案。

我們做兩個(gè)實(shí)驗(yàn)

// 例子一
Number(9007199254740999)  // 9007199254741000   超過(guò)最大安全整數(shù),轉(zhuǎn)換時(shí),精度丟失。

// 例子二
var x = 9007199254740992;
var y = -x;
x == x + 1; // true 
y == y - 1; // true

解決辦法

將較大數(shù)字類型的ID,以String類型傳遞給前端。

總結(jié)

在kotlin項(xiàng)目中,ID是使用ID生成器生成的18位整數(shù),但是JavaScript中Number最大的安全整數(shù)為16位。生成的ID超過(guò)了最大安全數(shù),故在JSON解析時(shí),發(fā)生精度丟失。因此,推薦使用String類型來(lái)傳遞較大整數(shù)。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最近為Prong開(kāi)發(fā)了一個(gè)基于snowflake算法的Java分布式ID組件,將實(shí)體主鍵從原來(lái)的String類型的...
    大浪滔滔閱讀 24,139評(píng)論 2 16
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,920評(píng)論 0 13
  • JavaScript語(yǔ)言精粹 前言 約定:=> 表示參考相關(guān)文章或書(shū)籍; JS是JavaScript的縮寫(xiě)。 本書(shū)...
    微笑的AK47閱讀 659評(píng)論 0 3
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 1,392評(píng)論 0 15
  • 特別說(shuō)明,為便于查閱,文章轉(zhuǎn)自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 270評(píng)論 0 0

友情鏈接更多精彩內(nèi)容