摘要:我們可以利用該函數(shù)限定返回?cái)?shù)值的位數(shù),從而達(dá)到提高精度的效果。
一、問題的引入
今天在看基礎(chǔ)js文章的時(shí)候發(fā)現(xiàn)了一個(gè)浮點(diǎn)數(shù)的精度問題,當(dāng)打印小數(shù)相加的時(shí)候有時(shí)候會出現(xiàn)數(shù)值不準(zhǔn)確的情況,如果是在做一些需要數(shù)據(jù)精度要求較高的工作的時(shí)候稍有不慎就會出現(xiàn)問題
console.log(0.1+0.1) //0.2 console.log(0.1+0.2) //0.30000000000000004(精度最高保留到17位)
查閱資料之后,發(fā)現(xiàn)是因?yàn)橄?0.1+0.2這樣的操作對于計(jì)算機(jī)來說轉(zhuǎn)換為二進(jìn)制之后將是兩個(gè)無限循環(huán)的數(shù)。而對于計(jì)算機(jī)而言是不允許有無限的,進(jìn)行四舍五入之后雙精度浮點(diǎn)數(shù)保留52位,結(jié)果為0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100轉(zhuǎn)為十進(jìn)制就是0.30000000000000004
二、基本解決方法【1】利用toFixed(digits)
toFixed函數(shù)在digits參數(shù)存在的情況下返回一個(gè)所給數(shù)值的定點(diǎn)數(shù)表示法的字符串(digits要在0-20之間,默認(rèn)為0)。我們可以利用該函數(shù)限定返回?cái)?shù)值的位數(shù),從而達(dá)到提高精度的效果。
var floatNum=0.1+0.2; console.log(floatNum); //0.30000000000000004 console.log(floatNum.toFixed(2)) //0.30 console.log(1.35.toFixed(1)) //1.4 console.log(1.33335.toFixed(4)); //1.3334
在這里我們看上去是解決了問題,但是和直接進(jìn)行相加一樣有時(shí)候toFixed 也會有問題
Chrome: console.log(1.55.toFixed(1));// 1.6 console.log(1.555.toFixed(2));//1.55 console.log(1.5555.toFixed(3));//1.556
關(guān)于這個(gè)問題,MDN上函數(shù)的描述為 “該數(shù)值在必要時(shí)進(jìn)行四舍五入,另外在必要時(shí)會用 0 來填充小數(shù)部分,以便小數(shù)部分有指定的位數(shù)。”至于是怎么定義“必要”的,不同的瀏覽器會有不同的情況。
IE: console.log(1.55.toFixed(1)); //1.6 console.log(1.555.toFixed(2)); //1.56 console.log(1.5555.toFixed(3)); //1.556
【2】重寫toFixed函數(shù)
思路為放大原有的數(shù)據(jù),利用整數(shù)的整除來避免精度丟失
function toFixed(num, s) { if(typeof s==="undefined"){ return parseInt(num)+""; } if(typeof s!=="number"){ return "請正確輸入保留位數(shù)(數(shù)字)"; } var times = Math.pow(10, s); var newNum = num * times+0.5;//加0.5是為了實(shí)現(xiàn)四舍五入中"入"的那0.5 newNum = parseInt(newNum) / times; return newNum + ""http://toFixed返回的是字符類型的數(shù)據(jù) } console.log(toFixed(1.5)) //2 console.log(toFixed(1.55,1)) //1.6 console.log(toFixed(1.555,2)) //1.56 console.log(toFixed(1.5555,3)) //1.556
【3】基礎(chǔ)運(yùn)算自實(shí)現(xiàn)
function getDecimalLength(num){ //獲取小數(shù)位長度 let length=0; try{ length =String(num).split(".")[1].length }catch(e){ //TODO handle the exception } return length; } function getBeishu(num1,num2){ //獲取放大倍數(shù) let num1DecimalLength=getDecimalLength(num1); let num2DecimalLength=getDecimalLength(num2); let longer=Math.max(num1DecimalLength,num2DecimalLength); return Math.pow(10,longer); } //加減乘除算法 function add(num1,num2){ let beishu=getBeishu(num1,num2); return (num1*beishu+num2*beishu)/beishu; } function sub(num1,num2){ let beishu=getBeishu(num1,num); return (num1*beishu-num2*beishu)/beishu; } function mul(num1,num2){ let num1DecLen=getDecimalLength(num1); let num2DecLen=getDecimalLength(num2); let num1toStr=String(num1); let num2toStr=String(num2); return Number(num1toStr.replace(".",""))*Number(num2toStr.replace(".",""))/Math.pow(10,num1DecLen+num2DecLen) } function dev(num1,num2){ let num1DecLen=getDecimalLength(num1); let num2DecLen=getDecimalLength(num2); let num1toStr=String(num1); let num2toStr=String(num2); return Number(num1toStr.replace(".",""))/Number(num2toStr.replace(".",""))/Math.pow(10,num1DecLen-num2DecLen) }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/103087.html
摘要:前言最近,朋友問了我這樣一個(gè)問題在中的運(yùn)算結(jié)果,為什么是這樣的雖然我告訴他說,這是由于浮點(diǎn)數(shù)精度問題導(dǎo)致的。由于可以用階碼移動小數(shù)點(diǎn),因此稱為浮點(diǎn)數(shù)。它的實(shí)現(xiàn)遵循標(biāo)準(zhǔn),使用位精度來表示浮點(diǎn)數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018981071); 前言 最近,朋友 L 問了我這樣一個(gè)問題:在 chrome 中的運(yùn)算...
摘要:而的浮點(diǎn)數(shù)設(shè)置的偏移值是,因?yàn)橹笖?shù)域表現(xiàn)為一個(gè)非負(fù)數(shù),位,所以,實(shí)際的,所以。這是因?yàn)樗鼈冊谵D(zhuǎn)為二進(jìn)制時(shí)要舍入部分的不同可能造成的不同舍 IEEE 754 表示:你盡管抓狂、罵娘,但你能完全避開我,算我輸。 一、IEEE-754浮點(diǎn)數(shù)捅出的那些婁子 首先我們還是來看幾個(gè)簡單的問題,能說出每一個(gè)問題的細(xì)節(jié)的話就可以跳過了,而如果只能泛泛說一句因?yàn)镮EEE754浮點(diǎn)數(shù)精度問題,那么下文還是...
摘要:本文通過介紹的二進(jìn)制存儲標(biāo)準(zhǔn)來理解浮點(diǎn)數(shù)運(yùn)算精度問題,和理解對象的等屬性值是如何取值的,最后介紹了一些常用的浮點(diǎn)數(shù)精度運(yùn)算解決方案。浮點(diǎn)數(shù)精度運(yùn)算解決方案關(guān)于浮點(diǎn)數(shù)運(yùn)算精度丟失的問題,不同場景可以有不同的解決方案。 本文由云+社區(qū)發(fā)表 相信大家在平常的 JavaScript 開發(fā)中,都有遇到過浮點(diǎn)數(shù)運(yùn)算精度誤差的問題,比如 console.log(0.1+0.2===0.3)// fa...
摘要:又如,對于,結(jié)果其實(shí)并不是,但是最接近真實(shí)結(jié)果的數(shù),比其它任何浮點(diǎn)數(shù)都更接近。許多語言也就直接顯示結(jié)果為了,而不展示一個(gè)浮點(diǎn)數(shù)的真實(shí)結(jié)果了。小結(jié)本文主要介紹了浮點(diǎn)數(shù)計(jì)算問題,簡單回答了為什么以及怎么辦兩個(gè)問題為什么不等于。 原文地址:為什么0.1+0.2不等于0.3 先看兩個(gè)簡單但詭異的代碼: 0.1 + 0.2 > 0.3 // true 0.1 * 0.1 = 0.01000000...
摘要:基于這個(gè)問題運(yùn)動基礎(chǔ)問題,我想應(yīng)該也有一部分人沒有認(rèn)真對待過中浮點(diǎn)數(shù)的四則運(yùn)算出現(xiàn)的問題。解決方案引自解決方案為了解決浮點(diǎn)數(shù)運(yùn)算不準(zhǔn)確的問題,在運(yùn)算前我們把參加運(yùn)算的數(shù)先升級的的次方到整數(shù),等運(yùn)算完后再降級的的次方。 基于這個(gè)問題:javascript運(yùn)動基礎(chǔ)問題 ,我想應(yīng)該也有一部分人沒有認(rèn)真對待過js中浮點(diǎn)數(shù)的四則運(yùn)算出現(xiàn)的問題。 1.問題描述 示例代碼: var x ...
閱讀 2950·2023-04-26 01:32
閱讀 1543·2021-09-13 10:37
閱讀 2282·2019-08-30 15:56
閱讀 1676·2019-08-30 14:00
閱讀 3047·2019-08-30 12:44
閱讀 1966·2019-08-26 12:20
閱讀 1065·2019-08-23 16:29
閱讀 3233·2019-08-23 14:44