javascript中toFixed()四舍五入使用方法詳解
最近做的項(xiàng)目涉及到金額的計(jì)算,有一種方式就是進(jìn)行四舍五入的規(guī)則進(jìn)行小數(shù)點(diǎn)后面的尾數(shù)處理,以前一直以為toFixed方法就是四舍五入的,知道一個(gè)用戶反饋了金額計(jì)算的bug我才如夢(mèng)初醒(虧了一毛錢),才仔細(xì)深究了下toFixed這個(gè)方法,唉,還是我不夠嚴(yán)謹(jǐn)啊,前車之鑒,大家勿走我的老路!
toFixed還不同的瀏覽器實(shí)現(xiàn),在IE10及以上里面是正常的四舍五入,但是別的瀏覽器里面就不一樣了,它不是正常的四舍五入(等下重點(diǎn)說(shuō)),比如:
var a = 1.335; console.log(a.toFixed(2)) // IE 1.34 //chorme 1.33
其他的瀏覽器我沒(méi)去一一測(cè)試,所以如果大家用了其他瀏覽器的還是需要去實(shí)際測(cè)試一下,我這里就說(shuō)說(shuō)javascript的toFixed()方法的四舍五入原理:
toFixed它是一個(gè)四舍六入五成雙的詭異的方法(也叫銀行家算法),"四舍六入五成雙"含義:對(duì)于位數(shù)很多的近似數(shù),當(dāng)有效位數(shù)確定后,其后面多余的數(shù)字應(yīng)該舍去,只保留有效數(shù)字最末一位,這種修約(舍入)規(guī)則是“四舍六入五成雙”,也即“4舍6入5湊偶”這里“四”是指≤4 時(shí)舍去,"六"是指≥6時(shí)進(jìn)上,"五"指的是根據(jù)5后面的數(shù)字來(lái)定,當(dāng)5后有數(shù)時(shí),舍5入1;當(dāng)5后無(wú)有效數(shù)字時(shí),需要分兩種情況來(lái)講:①5前為奇數(shù),舍5入1;②5前為偶數(shù),舍5不進(jìn)。(0是偶數(shù))
但是,經(jīng)過(guò)我的測(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ù)中還是少用,
最好別用,否則可能會(huì)出大問(wèn)題!
下面再再說(shuō)說(shuō)我自己的做法,就是根據(jù)精確位數(shù)來(lái)取小數(shù)點(diǎn)后的數(shù),然后判斷精確位是大于4還是小于等于4,上代碼吧,不說(shuō)了:
我們的業(yè)務(wù)是最多精確到分,也就是兩位小數(shù),最少就是取整,不留小數(shù)
function moneySwitch(money, precision){//precision是需要精確的位數(shù),如百分位就是2 var result = 0; //先進(jìn)行一個(gè)千分位的四舍五入,保證3.0999這種情況在保留一位小數(shù)的時(shí)候能是對(duì)的,這一位可以這么做沒(méi)什么問(wèn)題 var money = parseFloat(money).toFixed(3); try{ var int_part = money.split(".")[0], //小數(shù)點(diǎn)前的整數(shù) point_num = money.split(".")[1],//取小數(shù)點(diǎn)后面的小數(shù) precision_num = point_num[3-precision]; if(precision_num>4){//五入的情況 if(precision==1){ point_num = parseInt(point_num)+10+""; if(point_num.length>3){//說(shuō)明往整數(shù)位進(jìn)1 int_part = parseInt(int_part)+1+""; point_num = point_num[1]+point_num[2]; }else{ point_num = point_num[0]+point_num[1]; } result = parseFloat(int_part+"."+point_num); }else if(precision==2){ point_num = parseInt(point_num)+100+""; if(point_num.length>3){//說(shuō)明往整數(shù)位進(jìn)1 int_part = parseInt(int_part)+1+""; point_num = point_num[1]; }else{ point_num = point_num[0]; } result = parseFloat(int_part+"."+point_num); }else if(precision==3){ int_part = parseInt(int_part)+1+""; point_num = 0; } result = parseFloat(int_part+"."+point_num); }else{//四舍的情況 if(precision==1){ point_num = point_num[0]+point_num[1]; }else if(precision==2){ point_num = point_num[0]; }else if(precision==3){ point_num = 0; } result = parseFloat(int_part+"."+point_num); } }catch(e){ return parseFloat(money).toFixed(2);//如果過(guò)程中有出錯(cuò)就tofixed代替為解決 } return result; }
補(bǔ)充:
js處理數(shù)字保留2位小數(shù),強(qiáng)制保留2位小數(shù)不夠補(bǔ)上.00
1、保留兩位小數(shù) //功能:將浮點(diǎn)數(shù)四舍五入,取小數(shù)點(diǎn)后2位
2、//制保留2位小數(shù),如:2,會(huì)在2后面補(bǔ)上00.即2.00
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Test</title> <script type="text/javascript" src="js/jq.js"></script> </head> <script type="text/javascript"> //保留兩位小數(shù) //功能:將浮點(diǎn)數(shù)四舍五入,取小數(shù)點(diǎn)后2位 function toDecimal(x) { var f = parseFloat(x); if (isNaN(f)) { return; } f = Math.round(x*100)/100; return f; } //制保留2位小數(shù),如:2,會(huì)在2后面補(bǔ)上00.即2.00 function toDecimal2(x) { var f = parseFloat(x); if (isNaN(f)) { return false; } var f = Math.round(x*100)/100; var s = f.toString(); var rs = s.indexOf('.'); if (rs < 0) { rs = s.length; s += '.'; } while (s.length <= rs + 2) { s += '0'; } return s; } function fomatFloat(src,pos){ return Math.round(src*Math.pow(10, pos))/Math.pow(10, pos); } document.write("四舍五入 <br/>") document.write("3.14159267保留2位小數(shù):" + toDecimal(3.14159267)+"<br/>"); document.write("3.14159267強(qiáng)制保留2位小數(shù):" + toDecimal2(3.14159267)+"<br/>"); document.write("3.14159267保留2位小數(shù):" + toDecimal(3.14559267)+"<br/>"); document.write("3.14159267強(qiáng)制保留2位小數(shù):" + toDecimal2(3.15159267)+"<br/>"); document.write("3.14159267保留2位小數(shù):" + fomatFloat(3.14559267, 2)+"<br/>"); document.write("3.14159267保留1位小數(shù):" + fomatFloat(3.15159267, 1)+"<br/>"); document.write("五舍六入 <br/>") document.write("1000.003保留2位小數(shù):" + 1000.003.toFixed(2)+"<br/>"); document.write("1000.08保留1位小數(shù):" + 1000.08.toFixed(1)+"<br/>"); document.write("1000.04保留1位小數(shù):" + 1000.04.toFixed(1)+"<br/>"); document.write("1000.05保留1位小數(shù):" + 1000.05.toFixed(1)+"<br/>"); document.write("科學(xué)計(jì)數(shù) <br/>") document.write(3.1415+"科學(xué)技術(shù)后:"+3.1415.toExponential(2)+"<br/>"); document.write(3.1455+"科學(xué)技術(shù)后:"+3.1455.toExponential(2)+"<br/>"); document.write(3.1445+"科學(xué)技術(shù)后:"+3.1445.toExponential(2)+"<br/>"); document.write(3.1465+"科學(xué)技術(shù)后:"+3.1465.toExponential(2)+"<br/>"); document.write(3.1665+"科學(xué)技術(shù)后:"+3.1665.toExponential(1)+"<br/>"); document.write("精確到n位,不含n位 <br/>") document.write("3.1415精確到小數(shù)點(diǎn)第2位" + 3.1415.toPrecision(2)+"<br/>"); document.write("3.1455精確到小數(shù)點(diǎn)第3位" + 3.1465.toPrecision(3)+"<br/>"); document.write("3.1445精確到小數(shù)點(diǎn)第2位" + 3.1415.toPrecision(2)+"<br/>"); document.write("3.1465精確到小數(shù)點(diǎn)第2位" + 3.1455.toPrecision(2)+"<br/>"); document.write("3.166592679287精確到小數(shù)點(diǎn)第5位" + 3.141592679287.toPrecision(5)+"<br/>"); </script> <body> <input type="text" id="Score" /> </body> </html>
這篇關(guān)于toFixed()的文章就介紹到這了,希望大家以后多多支持腳本之家。
- 盤(pán)點(diǎn)javascript 正則表達(dá)式中 中括號(hào)的【坑】
- JS使用tofixed與round處理數(shù)據(jù)四舍五入的區(qū)別
- JS處理數(shù)據(jù)四舍五入(tofixed與round的區(qū)別詳解)
- js正則表達(dá)式簡(jiǎn)單校驗(yàn)方法
- js用正則表達(dá)式篩選年月日的實(shí)例方法
- JS中toFixed()方法四舍五入的精度問(wèn)題詳解
- JavaScript 正則表達(dá)式詳解
- jmeter實(shí)現(xiàn)接口關(guān)聯(lián)的兩種方式(正則表達(dá)式提取器和json提取器)
- 在nest.js中通過(guò)正則表達(dá)式正確設(shè)置驗(yàn)證的方法
- jJavaScript中toFixed()和正則表達(dá)式的坑
相關(guān)文章
javascript自適應(yīng)寬度的瀑布流實(shí)現(xiàn)思路
這里主要介紹瀑布流的一種實(shí)現(xiàn)方法:絕對(duì)定位(css)+javascript+ajax+json。簡(jiǎn)單一點(diǎn)如果不做滾動(dòng)加載的話就是絕對(duì)定位(css)+javascript了,ajax和json是滾動(dòng)加載更多內(nèi)容的時(shí)候用到的,感興趣的你可以參考下哦2013-02-02利用JS實(shí)現(xiàn)頁(yè)面刪除并重新排序功能
這篇文章主要介紹了利用JS實(shí)現(xiàn)頁(yè)面刪除并重新排序功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12JS實(shí)現(xiàn)為表格動(dòng)態(tài)添加標(biāo)題的方法
這篇文章主要介紹了JS實(shí)現(xiàn)為表格動(dòng)態(tài)添加標(biāo)題的方法,涉及javascript中createCaption方法添加標(biāo)題的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03javascript用rem來(lái)做響應(yīng)式開(kāi)發(fā)
這篇文章主要介紹了javascript用rem來(lái)做響應(yīng)式開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-018個(gè)JavaScript中高階函數(shù)的運(yùn)用分享
高階函數(shù)是指以函數(shù)作為參數(shù)的函數(shù),并且可以將函數(shù)作為結(jié)果返回的函數(shù)。本文整理了8個(gè)JavaScript中高階函數(shù)的運(yùn)用,需要的可以參考一下2023-04-04擴(kuò)展bootstrap的modal模態(tài)框-動(dòng)態(tài)添加modal框-彈出多個(gè)modal框
這篇文章主要介紹了擴(kuò)展bootstrap的modal模態(tài)框-動(dòng)態(tài)添加modal框-彈出多個(gè)modal框,需要的朋友可以參考下2017-02-02Js通過(guò)AES加密后PHP用Openssl解密的方法
這篇文章主要給大家介紹了關(guān)于Js如何通過(guò)AES加密后PHP利用Openssl解密的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07