js处理java后端接口返回long值解析不准确的问题
在工作中,遇到一個問題,明明后端接口返回的id是16437976441985843999(只是舉例),但是用這個id去查詢詳情接口時總是報錯,后端開發人員查了日志是傳的id不對,實際是16437976441985843000,瀏覽器接口返回的id和后端原本給的id竟然不一致,查了相關文檔:
在Long長度大于17位時,就會出現精度丟失的問題
簡單解釋就是:JS自身Number類型的設計原因,原生JS不完全支持long
根本原因:
計算機的二進制實現和位數限制有些數無法有限表示。就像一些無理數不能有限表示,如 圓周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 規范,采用雙精度存儲(double precision),占用 64 bit,如圖:
其中:1位用來表示符號位;11位用來表示指數;52位表示尾數
浮點數,比如
此時只能模仿十進制進行四舍五入了,但是二進制只有 0 和 1 兩個,于是變為 0 舍 1 入。這即是計算機中部分浮點數運算時出現誤差,丟失精度的根本原因。
大整數的精度丟失和浮點數本質上是一樣的,尾數位最大是 52 位,因此 JS 中能精準表示的最大整數是 Math.pow(2, 53),十進制即 9007199254740992。大于 9007199254740992 的可能會丟失精度
看似有窮的數字, 在計算機的二進制表示里卻是無窮的,由于存儲位數限制因此存在“舍去”,精度丟失就發生了。
對于前后臺傳參Long類型而言,JS內置有32位整數,而number類型的安全整數是53位。如果超過53位,則精度會丟失。如果后臺傳來一個64位的Long型整數,因為超過了53位,所以后臺返回的值和前臺獲取的值會不一樣。下面看一下如何處理這種精度丟失問題。
(以上對于根本原因的解釋:原文鏈接:https://blog.csdn.net/u010028869/java/article/details/86563382)
解決辦法:
1. 最直接的后端人員可把long型值轉成String類型給前端,這里主要介紹前端解決方案
2.端實現一個json parser
1>第一步,安裝 -- jison
npm install jison
2> 第二步,新增兩個文件,并修改其中一個文件關于Number類型轉換的邏輯
在githubhttps://github.com/zaach/jsonlint/tree/master/src這個鏈接下載 jsonlint.l 、jinsonlint.y 放在本地文件夾下,在此以公司的vue項目為例,放在static目錄下:,如圖
這兩個文件分別是 詞表文件 - lexfile - jsonlint.l、語法文件 - grammFile - jsonlint.y
修改 jsonlint.y 詞法文件關于JSONNumber的這段代碼:
源代碼這樣:
修改后:
3> 第三步,生成我們要的 jsonlint.js
用第一步jison把第二步的兩位文件合成一個我們要的最終插件,在控制臺輸入:
4> 第四步,引入jsonlint.js文件,以便使用
5> 第五步,在我們自己axios封裝的request.js中使用:
最后,我們就可以在接口里看到精確的Long型值了。
(參考自:https://blog.csdn.net/fifteen718/article/details/82783246?utm_source=blogxgwz9)
總結
以上是生活随笔為你收集整理的js处理java后端接口返回long值解析不准确的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Angulary应用依赖里的zone.j
- 下一篇: 一些能提高ABAP开发人员日常工作效率的