js tofixed精度丟失問題

2022-09-19 10:27:07 字數 2049 閱讀 3247

tofixed() 方法可把 number 四捨五入為指定小數字數的數字。例如將資料num保留2位小數,則表示為:tofixed(num);

但是其四捨五入的規則與數學中的規則不同,使用的是銀行家捨入規則,

銀行家捨入:所謂銀行家捨入法,其實質是一種四捨六入五取偶(又稱四捨六入五留雙)法。具體規則如下:簡單來說就是:四捨六入五考慮,五後非零就進一,五後為零看奇偶,五前為偶應捨去,五前為奇要進一。

經測試發現,在chorme下面,並沒有完全遵守這個規則,尤其是5的後面沒有數字的時候,不是這麼判斷的,如下:

var b = 1.335

b.tofixed(2)

"1.33"

var b = 1.345

b.tofixed(2)

"1.34"

var b = 1.355

b.tofixed(2)

"1.35"

var b = 1.365

b.tofixed(2)

"1.36"

var b = 1.375

b.tofixed(2)

"1.38"

var b = 1.385

b.tofixed(2)

"1.39"

可以發現在chorme下沒有完全去遵循這個規律,或許它有自己的演算法,但是畢竟它沒有遵循通用的銀行家演算法,所以tofixed這個方法在涉及到金錢計算的業務中還是少用.

總而言之:不論引入tofixed解決浮點數計算精度缺失的問題也好,它有沒有使用銀行家捨入法也罷,都是為了解決精度的問題,但是又離不開二進位制浮點數的環境,但至少他幫助我們找到了問題所在,從而讓我們有解決方法。

一開始的辦法是把要四捨五入的後一位單獨拎出來單獨判斷。

number.prototype.tofixed = function (n) 

return result;

}

然後又發現計算機二進位制編碼導致的精度問題。

自己debugger,發現頁面中的js進了死迴圈。很明顯問題出在tofixed中**了tofixed,結果沒有走出來,繼續debugger,又有了驚人的發現。以下是控制台測試:

console.log(2.115 * 100) // 211.50000000000003

console.log(2.0115 * 1000) // 2011.4999999999998

既然你一直進入迴圈,我就手動把你拉出來。

result = (math.round((parsefloat(result)) * x) + 1) / x;

最終完整的重寫tofixed的方法

// tofixed相容方法

number.prototype.tofixed = function (n)

const number = this;

if (isnan(number) || number >= math.pow(10, 21))

if (typeof (n) == 'undefined' || n == 0)

let result = number.tostring();

const arr = result.split('.');

// 整數的情況

if (arr.length < 2)

return result;

}const integer = arr[0];

const decimal = arr[1];

if (decimal.length == n)

if (decimal.length < n)

return result;

}result = integer + '.' + decimal.substr(0, n);

const last = decimal.substr(n, 1);

// 四捨五入,轉換為整數再處理,避免浮點數精度的損失

if (parseint(last, 10) >= 5)

return result;

}

cJSON精度丟失問題

問題復現步驟 1 輸入字串 2 字串轉成cjson物件 3 呼叫cjson print將cjson物件再轉成字串 4 再將字串轉成cjson物件 5 保留8位精度方式呼叫printf列印值,輸出變成 0.123456 問題的原因出在cjson的print number函式 static char p...

Long型別精度丟失問題

js long型別經度丟失 解決方案 後端將long型別引數轉為字串後返回給前端 在單個long型別的引數上加上 import com.fasterxml.jackson.databind.annotation.jsonserialize jsonserialize using tostringse...

運算精度丟失和數值丟失問題

標籤 空格分隔 程式設計競賽 程式設計錯題 在做題時,我經常會碰到程式很對,但結果出錯的問題。如下面這個。題目描述 經常出國旅行的驢友都知道,需要及時了解當地的氣溫狀況。但不少國家採用了不同的溫度計量單位 有些使用華氏溫度標準 f 有些使用攝氏溫度 c 現在,請你根據溫度轉換公式設計乙個溫度轉換程式...