欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中toFixed(2)精度問(wèn)題的原因以及解決辦法

 更新時(shí)間:2024年04月29日 11:51:54   作者:喝一杯維C  
最近發(fā)現(xiàn)JS當(dāng)中toFixed()方法存在一些問(wèn)題,所以這里給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于JS中toFixed(2)精度問(wèn)題的原因以及解決辦法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

toFixed() 方法可把 Number 四舍五入為指定小數(shù)位數(shù)的數(shù)字。例如將數(shù)據(jù)Num保留2位小數(shù),則表示為:toFixed(Num);但是其四舍五入的規(guī)則與數(shù)學(xué)中的規(guī)則不同,使用的是銀行家舍入規(guī)則,銀行家舍入:所謂銀行家舍入法,其實(shí)質(zhì)是一種四舍六入五取偶(又稱四舍六入五留雙)法。具體規(guī)則如下:簡(jiǎn)單來(lái)說(shuō)就是:四舍六入五考慮,五后非零就進(jìn)一,五后為零看奇偶,五前為偶應(yīng)舍去,五前為奇要進(jìn)一。

經(jīng)測(cè)試發(fā)現(xiàn),在chorme下面,并沒(méi)有完全遵守這個(gè)規(guī)則,尤其是5的后面沒(méi)有數(shù)字的時(shí)候,不是這么判斷的,如下:

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"

可以發(fā)現(xiàn)在chorme下沒(méi)有完全去遵循這個(gè)規(guī)律,或許它有自己的算法,但是畢竟它沒(méi)有遵循通用的銀行家算法,所以tofixed這個(gè)方法在涉及到金錢計(jì)算的業(yè)務(wù)中還是少用.

總而言之:不論引入toFixed解決浮點(diǎn)數(shù)計(jì)算精度缺失的問(wèn)題也好,它有沒(méi)有使用銀行家舍入法也罷,都是為了解決精度的問(wèn)題,但是又離不開(kāi)二進(jìn)制浮點(diǎn)數(shù)的環(huán)境,但至少他幫助我們找到了問(wèn)題所在,從而讓我們有解決方法。

一開(kāi)始的辦法是把要四舍五入的后一位單獨(dú)拎出來(lái)單獨(dú)判斷。

解決方法:

通過(guò)重寫toFixed方法:

Number.prototype.toFixed = function (n) {
let result = number.toString();
const arr = result.split('.');
const integer = arr[0];
const decimal = arr[1];
result = integer + '.' + decimal.substr(0, n);
const last = decimal.substr(n, 1);

// 四舍五入,轉(zhuǎn)換為整數(shù)再處理,避免浮點(diǎn)數(shù)精度的損失

if (parseInt(last, 10) >= 5) {
const x = Math.pow(10, n);
result = ((parseFloat(result) * x) + 1) / x;
result = result.toFixed(n);
}
return result;
}

然后又發(fā)現(xiàn)計(jì)算機(jī)二進(jìn)制編碼導(dǎo)致的精度問(wèn)題,詳見(jiàn)上一篇博客。

自己debugger,發(fā)現(xiàn)頁(yè)面中的js進(jìn)了死循環(huán)。很明顯問(wèn)題出在toFixed中回調(diào)了toFixed,結(jié)果沒(méi)有走出來(lái),繼續(xù)debugger,又有了驚人的發(fā)現(xiàn)。以下是控制臺(tái)測(cè)試:

console.log(2.115 * 100) // 211.50000000000003
console.log(2.0115 * 1000) // 2011.4999999999998

既然你一直進(jìn)入循環(huán),我就手動(dòng)把你拉出來(lái)。

result = (Math.round((parseFloat(result)) * x) + 1) / x;

最終完整的重寫toFixed的方法

// toFixed兼容方法
Number.prototype.toFixed = function (n) {
    if (n > 20 || n < 0) {
        throw new RangeError('toFixed() digits argument must be between 0 and 20');
    }
    const number = this;
    if (isNaN(number) || number >= Math.pow(10, 21)) {
        return number.toString();
    }
    if (typeof (n) == 'undefined' || n == 0) {
        return (Math.round(number)).toString();
    }
    let result = number.toString();
    const arr = result.split('.');
    // 整數(shù)的情況
    if (arr.length < 2) {
        result += '.';
        for (let i = 0; i < n; i += 1) {
            result += '0';
        }
        return result;
    }
    const integer = arr[0];
    const decimal = arr[1];
    if (decimal.length == n) {
        return result;
    }
    if (decimal.length < n) {
        for (let i = 0; i < n - decimal.length; i += 1) {
            result += '0';
        }
        return result;
    }
    result = integer + '.' + decimal.substr(0, n);
    const last = decimal.substr(n, 1);
    // 四舍五入,轉(zhuǎn)換為整數(shù)再處理,避免浮點(diǎn)數(shù)精度的損失
    if (parseInt(last, 10) >= 5) {
        const x = Math.pow(10, n);
        result = (Math.round((parseFloat(result) * x)) + 1) / x;
        result = result.toFixed(n);
    }
    return result;
}

總結(jié) 

到此這篇關(guān)于JS中toFixed(2)精度問(wèn)題的原因以及解決辦法的文章就介紹到這了,更多相關(guān)js toFixed(2)精度問(wèn)題解決內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Javscript刪除數(shù)組中指定元素并返回新數(shù)組

    Javscript刪除數(shù)組中指定元素并返回新數(shù)組

    把數(shù)組中某個(gè)值刪除,并返回新數(shù)組,需要遍歷舊數(shù)組找到要?jiǎng)h除的元素,下面有個(gè)不錯(cuò)的示例,大家可以參考下
    2014-03-03
  • 如何利用echarts畫雷達(dá)圖和折柱混合

    如何利用echarts畫雷達(dá)圖和折柱混合

    最近使用echarts做的一個(gè)H5的成績(jī)數(shù)據(jù)報(bào)告,里面使用了雷達(dá)圖已經(jīng)折線圖和柱狀圖,下面這篇文章主要給大家介紹了關(guān)于如何利用echarts畫雷達(dá)圖和折柱混合的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 創(chuàng)建與框架無(wú)關(guān)的JavaScript插件

    創(chuàng)建與框架無(wú)關(guān)的JavaScript插件

    這篇文章主要介紹了創(chuàng)建與框架無(wú)關(guān)的JavaScript插件,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下
    2020-12-12
  • uniapp中vuex的應(yīng)用使用步驟

    uniapp中vuex的應(yīng)用使用步驟

    Vuex是一個(gè)專為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式,它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化,下面這篇文章主要給大家介紹了關(guān)于uniapp中vuex的應(yīng)用使用,需要的朋友可以參考下
    2022-08-08
  • 詳細(xì)聊聊JavaScript是如何影響DOM樹(shù)構(gòu)建的

    詳細(xì)聊聊JavaScript是如何影響DOM樹(shù)構(gòu)建的

    DOM (Document Object Model) 的全稱是文檔對(duì)象模型,它可以以一種獨(dú)立于平臺(tái)和語(yǔ)言的方式訪問(wèn)和修改一個(gè)文檔的內(nèi)容和結(jié)構(gòu),這篇文章主要給大家介紹了關(guān)于JavaScript是如何影響DOM樹(shù)構(gòu)建的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • js獲取div高度的代碼

    js獲取div高度的代碼

    不錯(cuò)的獲取div高度的代碼,主要是方便測(cè)試一些信息,用到了javascript的offsetHeight屬性
    2008-08-08
  • 老生常談JavaScript 函數(shù)表達(dá)式

    老生常談JavaScript 函數(shù)表達(dá)式

    下面小編就為大家?guī)?lái)一篇老生常談JavaScript 函數(shù)表達(dá)式。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • 兼容ie和firefox的鼠標(biāo)經(jīng)過(guò)(onmouseover和onmouseout)實(shí)現(xiàn)--簡(jiǎn)短版

    兼容ie和firefox的鼠標(biāo)經(jīng)過(guò)(onmouseover和onmouseout)實(shí)現(xiàn)--簡(jiǎn)短版

    兼容ie和firefox的鼠標(biāo)經(jīng)過(guò)(onmouseover和onmouseout)實(shí)現(xiàn)--簡(jiǎn)短版...
    2007-11-11
  • JavaScript為事件句柄綁定監(jiān)聽(tīng)函數(shù)實(shí)例詳解

    JavaScript為事件句柄綁定監(jiān)聽(tīng)函數(shù)實(shí)例詳解

    這篇文章主要介紹了JavaScript為事件句柄綁定監(jiān)聽(tīng)函數(shù)的方法,結(jié)合實(shí)例詳細(xì)分析了常見(jiàn)的事件句柄綁定監(jiān)聽(tīng)函數(shù)的實(shí)現(xiàn)技巧,并實(shí)例講解了跨瀏覽器的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2015-12-12
  • js中如何對(duì)嵌套數(shù)組進(jìn)行filter過(guò)濾

    js中如何對(duì)嵌套數(shù)組進(jìn)行filter過(guò)濾

    這篇文章主要介紹了js中如何對(duì)嵌套數(shù)組進(jìn)行filter過(guò)濾問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06

最新評(píng)論