javascript 精度問題導致後端傳過來的值顯示不正確,有何好的解決辦法?

時間 2021-05-08 20:10:40

1樓:小紅

前幾天用vuetify寫了點東西,發現乙個細節。 https://vuetifyjs.com/en/components/text-fields

text-fields中的值,後台傳過來json的,如果屬性是整數,那麼渲染的時候還保留數字型別,例如1還是1。如果是小數,就自動變成字串,例如1.11,debug看的時候就變成了'1.

11'。版本是vuetify 1.1。

因為涉及到一些內容判斷,所以在這裡踩了個坑。後來思考了下為什麼,覺得還是蠻好的設計,之前做另乙個報表系統的時候,用angular+typescript的組合也沒能阻擋浮點的各種隨機尾數,這裡用string就給自動截住了。

2樓:小寺川

上面都提到了用 string, 事實上另外乙個讓伺服器處理的原因是多客戶端都需要處理同樣的問題, 比如 web, RN 等等. 伺服器傳 string 能保證一致性切不需要多種客戶端實現, 從而減少 bug 的可能性.

3樓:馬面

1、後端要盡量返回精確資料,而不能為了相容大前端的展示效果而對精度進行擷取(如通常的保留2位小數)。

一方面後端服務A的結果可能是另乙個後端服務B的入口,A必須精確B才能正常執行。

另一方面是各前端對展示效果要求可能不同(如小程式端可能只需要展示整數)。

2、前端可以用string接收後端的的精確資料

3、另外,如果發現後端返回的是小數字數特別長的資料,要排查一下是不是以double型別接收資料了?有時候後端返回了BigDecimal型別的精確資料(如只有2位小數),前端使用double來接收才導致的小數字數特別長。此時直接使用postman等工具除錯介面就可以看到後端返回的確實是2位小數

4樓:黒之

寫個字串遍歷,粗暴點把所有int型別轉string,精確點只轉超過16位的。之後再JSON.parse

不過根據經驗來講,你不是要加減乘除的話,用粗暴的就行,你要加減乘除,用粗暴的一樣行(要加個big.js

Big.js

畢竟都涉及這麼大的數字計算了,用個庫不過分吧?

我同時寫過前後端,自己寫介面自己調,覺得後端能方便前端那是最好,但是很多情況下,為了減輕後端計算壓力,很多計算都會放前端。所以我很理解不了,大部分前端就是想在前端只負責展示這個觀點。

對於你這個案例,我覺得前後端做都沒問題,建議剪刀石頭布解決

以下是我覺得應該放在前端寫的邏輯

比如,類似支付寶的賬單頁,ui要求按月分組(實際我們在月裡面還多乙個天的組),資料庫裡是不會分組的,那肯定是要寫乙個分組邏輯。我這邊前端說,要後端分好組再給。我問他,那你一頁要多少條資料?

是10條最細粒度的,還是10個有資料的天,還是10個有資料的月?對前端最友好的方法是按月,所以他直接回答10個月。

5樓:Kong丶猦

額,是JSON.parse 有問題,但是jquery的ajax請求,解析json是用的就是JSON.parse 不知道你們用的是什麼樣的。。。

6樓:

!!!簡單的解決方法,讓伺服器傳給你string型別

但是伺服器的人說了:

你們前端怎麼顯示個long都搞不定

複雜的方法,拿到JSON字串以後用正規表示式替換一下,將可能溢位的數字轉化為string

在其他語言中,long型別可以達到的最大值為

而在JS中,整形的最大的值為 Number.MAX_SAFE_INTEGER

如果溢位就會發生如下詭異的語句

9007199254740993

==9007199254740992

;//true

我們需要找到乙個檢測數字是否可能溢位的方法,想法是將類似於『123』的數字字串化為Number再將它轉化成String,如果和之前的String不相同那麼就發生了溢位

//false

String(Number('18446744073709551616'))=='18446744073709551616'

//true

String(Number('123'))=='123'

//詭異的結果們

//true

Number('18446744073709551616')=='18446744073709551616'

//true

String(18446744073709551616)=='18446744073709552000'

//true

18446744073709551616=='18446744073709552000'

所以最後的正則替換還是比較簡單的,此方法只適用於long

JSON

.parse

(jText

.replace

(/\b\d+\b/g

,replaceOverflow

));function

replaceOverflow

(yytext)"`

}-------更新----

其實上面的方法並不是乙個很好的解決方案,會替換掉不該替換的數字

{ "id":123

"des":"this is a long:999999999999999999999999999999"

}String中的數字是不能被替換的,為了避免這樣的情況,需要完全實現JSON字元的轉化,如果手寫parser的話,工作量十分巨大,事實上只需要在前人的輪子上稍稍改進即可。推薦乙個開源專案JISON (zaach/jison · GitHub)

也許你從來沒聽過把JS作為runtime來實現其他語言,但是JS真的可以,你可能需要回憶一下編譯原理的課程才能正確使用JISON。接下來,我們把JS作為runtime來翻譯JSON字串,語法檔案在這裡(jsonlint/jsonlint.y at master · zaach/jsonlint · GitHub),原始檔中,遇到數字時直接將其轉化為Number

JSONNumber

: NUMBER;

7樓:

讓伺服器端轉成字串,或者改ajax type為string,手動匹配一下,自己寫個簡單的高精度然後parse一下再把不正確的值替換為之前算出來的值.

8樓:賀師俊

js內建有32位整數,而number型別的安全整數是53位。如果超過53位的,你不能用json傳遞,需要用其他資料型別,比如字串,或拆分成兩個資料字段。

javascript原型的問題?

yibuyisheng 如果我記得沒錯的話,在ObjectiveC中,對物件成員的訪問被稱為傳送訊息。此處 例項.屬性 的形式在內部也是乙個傳送訊息的過程。也就是說,給例項傳送乙個訊息說 我想訪問你上面的某個屬性!例項收到這個訊息之後,就開始按照原型鏈的屬性查詢規則去查詢相應的屬性,找到就返回相應的...

舍友有嚴重心理問題報告導員但是導員無作為怎麼辦?

名字被重置了 我們學校每個院系都有負責心理這方面的老師,你可以問一下你們班的心理委員,然後直接聯絡這個老師。因為她的心理出現一些問題,最大的安全隱患是她,把這些小事拔高到她的生命安全,輔導員肯定會重視很多。 滴答滴 首先,大千世界不奇不有,遇到奇怪的人,多數時候只能自認倒霉和自我安慰。多給自己做做心...

為什麼twice轉型期乏力不是選歌問題導致的(看說明)

因為任何乙個TOP團和超一線團最後下坡路不好看,99 都是成員自己作死 miss a哪怕後期裴秀智一枝獨秀團也沒糊透,最後一次回歸也拿到了pak SISTAR也沒熬過七年之癢,但是人家至少好聚好散 反之為什麼少女時代 14年後開始走下坡路?為什麼AOA現在名存實亡?為什麼wonder girls的巔...