日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > HTML >内容正文

HTML

js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法

發(fā)布時(shí)間:2025/3/20 HTML 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

瀏覽器處理數(shù)字運(yùn)算時(shí)精度丟失的方法

  • 為什么0.1 + 0.2 不等于0.3。因?yàn)橛?jì)算機(jī)不能精確表示0.1, 0.2這樣的浮點(diǎn)數(shù),計(jì)算時(shí)使用的是帶有舍入誤差的數(shù)
  • 并不是所有的浮點(diǎn)數(shù)在計(jì)算機(jī)內(nèi)部都存在舍入誤差,比如0.5就沒(méi)有舍入誤差

1.出現(xiàn)的原因

計(jì)算機(jī)的二進(jìn)制實(shí)現(xiàn)和位數(shù)限制有些數(shù)無(wú)法有限表示。就像一些無(wú)理數(shù)不能有限表示,如 圓周率 3.1415926...,1.3333... 等。JS 遵循 IEEE 754 規(guī)范,采用雙精度存儲(chǔ)(double precision),占用 64 bit

  • 1位用來(lái)表示符號(hào)位
  • 11位用來(lái)表示指數(shù)
  • 52位表示尾數(shù)

比如:

0.1?>>?0.0001?1001?1001?1001…(1001無(wú)限循環(huán))
0.2?>>?0.0011?0011?0011?0011…(0011無(wú)限循環(huán))

此時(shí)只能模仿十進(jìn)制進(jìn)行四舍五入了,但是二進(jìn)制只有 0 和 1 兩個(gè),于是變?yōu)?0 舍 1 入。這即是計(jì)算機(jī)中部分浮點(diǎn)數(shù)運(yùn)算時(shí)出現(xiàn)誤差,丟失精度的根本原因。

大整數(shù)的精度丟失和浮點(diǎn)數(shù)本質(zhì)上是一樣的,尾數(shù)位最大是 52 位,因此 JS 中能精準(zhǔn)表示的最大整數(shù)是 Math.pow(2, 53),十進(jìn)制即 9007199254740992。

9007199254740992?+?1?//?丟失
9007199254740992?+?2?//?未丟失
9007199254740992?+?3?//?丟失
9007199254740992?+?4?//?未丟失

大于 9007199254740992 的可能會(huì)丟失精度,看似有窮的數(shù)字, 在計(jì)算機(jī)的二進(jìn)制表示里卻是無(wú)窮的,由于存儲(chǔ)位數(shù)限制因此存在“舍去”,精度丟失就發(fā)生了

2.如何解決

2.1

在每次計(jì)算的時(shí)候把小數(shù)放到位整數(shù)(乘倍數(shù)),再縮小回原來(lái)倍數(shù)(除倍數(shù)) 例:

2.2

第一種每次計(jì)算都要重復(fù)的去乘以和除以使得代碼不美觀,將下面方法封裝到utils工具中每次使用時(shí)去調(diào)用就可以了,這幾個(gè)方法原理上其實(shí)和第一種差不多的

//除法
function?accDiv(arg1,arg2){
????var?t1=0,t2=0,r1,r2;
????try{t1=arg1.toString().split(".")[1].length}catch(e){}
????try{t2=arg2.toString().split(".")[1].length}catch(e){}
????with(Math){
?????r1=Number(arg1.toString().replace(".",""))
?????r2=Number(arg2.toString().replace(".",""))
?????return?accMul((r1/r2),pow(10,t2-t1));
???}
?}????
?//乘法
?function?accMul(arg1,arg2){
???var?m=0,s1=arg1.toString(),s2=arg2.toString();
???try{m+=s1.split(".")[1].length}catch(e){}
???try{m+=s2.split(".")[1].length}catch(e){}
???return?Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
?}
//加法
function?accAdd(arg1,arg2){
???var?r1,r2,m;
???try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
???try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
???m=Math.pow(10,Math.max(r1,r2))
???return?(arg1*m+arg2*m)/m
}
//減法
function?Subtr(arg1,arg2){
???var?r1,r2,m,n;
???try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
???try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
???m=Math.pow(10,Math.max(r1,r2));
???n=(r1>=r2)?r1:r2;
???return?((arg1*m-arg2*m)/m).toFixed(n);
}
//?console.log(accMul(0.0003,10000))
//?console.log(0.0003*10000)

//?console.log(Subtr(0.999,0.998))
//?console.log(0.999-0.998)

//?console.log(accMul(0.0035,100))
//?console.log(0.0035*100)

//?console.log(accDiv(0.3,0.2))
//?console.log(0.3/0.2)

2.3

引入一些處理數(shù)字運(yùn)算的庫(kù),比如 Math.js 再去調(diào)用它提供出來(lái)的方法,個(gè)人認(rèn)為如果項(xiàng)目沒(méi)有要前端去處理金額之類的可以不用這種


《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。