偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我是這樣解決JavaScrip 加減乘除精度問題

開發(fā) 前端
眾所周知的 JavaScript 二進(jìn)制精度問題,浮點(diǎn)數(shù)的計(jì)算精度會(huì)存在缺失問題。最經(jīng)典的例子就是為什么0.1+0.2 !== 0.3

 前言

[[432194]]

眾所周知的 JavaScript 二進(jìn)制精度問題,浮點(diǎn)數(shù)的計(jì)算精度會(huì)存在缺失問題。最經(jīng)典的例子就是為什么0.1+0.2 !== 0.3

一句話概括就是:ECMAScript規(guī)范定義Number的類型遵循了IEEE754-2008中的64位浮點(diǎn)數(shù)規(guī)則定義的小數(shù)后的有效位數(shù)至多為52位導(dǎo)致計(jì)算出現(xiàn)精度丟失問題!

不過網(wǎng)上已經(jīng)有很多專門的類庫(kù)可以解決這個(gè)問題。

原生封裝

 

  1. /** 
  2.  ** 加法函數(shù),用來得到精確的加法結(jié)果 
  3.  ** 說明:javascript的加法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相加的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的加法結(jié)果。 
  4.  ** 調(diào)用:accAdd(arg1,arg2) 
  5.  ** 返回值:arg1加上arg2的精確結(jié)果 
  6.  **/ 
  7. function accAdd(arg1, arg2) { 
  8.     let r1, r2, m 
  9.     try { 
  10.         r1 = arg1.toString().split('.')[1].length 
  11.     } catch (e) { 
  12.         r1 = 0 
  13.     } 
  14.     try { 
  15.         r2 = arg2.toString().split('.')[1].length 
  16.     } catch (e) { 
  17.         r2 = 0 
  18.     } 
  19.     m = Math.pow(10, Math.max(r1, r2)) 
  20.     return (arg1 * m + arg2 * m) / m 

 

  1. /** 
  2.  ** 減法函數(shù),用來得到精確的減法結(jié)果 
  3.  ** 說明:javascript的減法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相減的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的減法結(jié)果。 
  4.  ** 調(diào)用:accSub(arg1,arg2) 
  5.  ** 返回值:arg1加上arg2的精確結(jié)果 
  6.  **/ 
  7. function accSub(arg1, arg2) { 
  8.   var r1, r2, m, n; 
  9.   try { 
  10.     r1 = arg1.toString().split(".")[1].length; 
  11.   } catch (e) { 
  12.     r1 = 0; 
  13.   } 
  14.   try { 
  15.     r2 = arg2.toString().split(".")[1].length; 
  16.   } catch (e) { 
  17.     r2 = 0; 
  18.   } 
  19.   m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //動(dòng)態(tài)控制精度長(zhǎng)度 
  20.   n = r1 >= r2 ? r1 : r2; 
  21.   return ((arg1 * m - arg2 * m) / m).toFixed(n); 

 

  1. /** 
  2.  ** 乘法函數(shù),用來得到精確的乘法結(jié)果 
  3.  ** 說明:javascript的乘法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相乘的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的乘法結(jié)果。 
  4.  ** 調(diào)用:accMul(arg1,arg2) 
  5.  ** 返回值:arg1乘以 arg2的精確結(jié)果 
  6.  **/ 
  7.   
  8. function accMul(arg1, arg2) { 
  9.     let m = 0 
  10.     let s1 = arg1.toString() 
  11.     let s2 = arg2.toString() 
  12.     try { 
  13.         m += s1.split('.')[1] ? s1.split('.')[1].length : '' 
  14.     } catch (e) {} 
  15.     try { 
  16.         m += s2.split('.')[1] ? s2.split('.')[1].length : '' 
  17.     } catch (e) {} 
  18.     return (Number(s1.replace('.''')) * Number(s2.replace('.'''))) / Math.pow(10, m) 

 

  1. /** 
  2.  ** 除法函數(shù),用來得到精確的除法結(jié)果 
  3.  ** 說明:javascript的除法結(jié)果會(huì)有誤差,在兩個(gè)浮點(diǎn)數(shù)相除的時(shí)候會(huì)比較明顯。這個(gè)函數(shù)返回較為精確的除法結(jié)果。 
  4.  ** 調(diào)用:accDiv(arg1,arg2) 
  5.  ** 返回值:arg1除以arg2的精確結(jié)果 
  6.  **/ 
  7. function accDiv(arg1, arg2) { 
  8.     let t1 = 0 
  9.     let t2 = 0 
  10.     let r1 
  11.     let r2 
  12.     try { 
  13.         t1 = arg1.toString().split('.')[1].length 
  14.     } catch (e) {} 
  15.     try { 
  16.         t2 = arg2.toString().split('.')[1].length 
  17.     } catch (e) {} 
  18.     r1 = Number(arg1.toString().replace('.''')) 
  19.     r2 = Number(arg2.toString().replace('.''')) 
  20.     return (r1 / r2) * Math.pow(10, t2 - t1) 

封裝

定義一個(gè)函數(shù)來調(diào)用加減乘除方法,這樣做有個(gè)好處,用到地方調(diào)用加減乘除方法一致,假設(shè)某個(gè)方法后面發(fā)現(xiàn)那個(gè)庫(kù)更好用或者某個(gè)平臺(tái)不兼容、算法不太嚴(yán)謹(jǐn)、擴(kuò)展新的功能等等,我們只要維護(hù)這個(gè)函數(shù)就行,不用在考慮項(xiàng)目中某個(gè)組件單獨(dú)引用,沒有按照這個(gè)規(guī)范因?yàn)檫@次維護(hù)引發(fā)的新問題。

 

  1. export const calcFn = { 
  2.     add() { 
  3.         const arg = Array.from(arguments) 
  4.         return arg.reduce((total, num) => { 
  5.             return accAdd(total, num) 
  6.         }) 
  7.     }, 
  8.     sub() { 
  9.         const arg = Array.from(arguments) 
  10.         return arg.reduce((total, num) => { 
  11.             return accSub(total, num) 
  12.         }) 
  13.     }, 
  14.     mul() { 
  15.         const arg = Array.from(arguments) 
  16.         return arg.reduce((total, num) => { 
  17.             return accMul(total, num) 
  18.         }) 
  19.     }, 
  20.     divide() { 
  21.         const arg = Array.from(arguments) 
  22.         return arg.reduce((total, num) => { 
  23.             return accDiv(total, num) 
  24.         }) 
  25.     } 

big.js

  • 介紹:任意精度十進(jìn)制算術(shù)的小型、快速、易于使用的庫(kù)。
  • 特性:目前同類型最小包、無依賴、包大小3 KB、兼容ECMAScript 3+可以說適用于所有瀏覽器。
  • 官網(wǎng):GitHub

 

 

 

 

https://github.com/MikeMcl/big.js/

安裝使用

瀏覽器

 

 

  1. <script src='https://cdn.jsdelivr.net/npm/big.js@6.1.1/big.min.js'></script> 

 

Node.js

  1. npm install big.js 

使用

 

  1. x = new Big(0.1) 
  2. y = new Big(0.2)                  
  3. z = new Big(0.3) 
  4. x.plus(y).eq(z)     // true 

運(yùn)算符操作函數(shù)

以下big.js目前支持運(yùn)算符操作函數(shù)。

  • abs,取絕對(duì)值。
  • cmp,compare的縮寫,即比較函數(shù)。
  • div,除法。
  • eq,equal的縮寫,即相等比較。
  • gt,大于。
  • gte,小于等于,e表示equal。
  • lt,小于。
  • lte,小于等于,e表示equal。
  • minus,減法。
  • mod,取余。
  • plus,加法。
  • pow,次方。
  • prec,按精度舍入,參數(shù)表示整體位數(shù)。
  • round,按精度舍入,參數(shù)表示小數(shù)點(diǎn)后位數(shù)。
  • sqrt,開方。
  • times,乘法。
  • toExponential,轉(zhuǎn)化為科學(xué)計(jì)數(shù)法,參數(shù)代表精度位數(shù)。
  • toFied,補(bǔ)全位數(shù),參數(shù)代表小數(shù)點(diǎn)后位數(shù)。
  • toJSON和toString,轉(zhuǎn)化為字符串。
  • toPrecision,按指定有效位數(shù)展示,參數(shù)為有效位數(shù)。
  • toNumber,轉(zhuǎn)化為JavaScript中number類型。
  • valueOf,包含負(fù)號(hào)(如果為負(fù)數(shù)或者-0)的字符串。

封裝

 

  1. import Big from 'big.js' 
  2.  
  3. export const calcFn = { 
  4.     add() { 
  5.         const arg = Array.from(arguments) 
  6.         return arg.reduce((total, num) => { 
  7.             return new Big(total).plus(new Big(num)) 
  8.         }).toString() * 1 
  9.     }, 
  10.     sub() { 
  11.         const arg = Array.from(arguments) 
  12.         return arg.reduce((total, num) => { 
  13.             return new Big(total).minus(new Big(num)) 
  14.         }).toString() * 1 
  15.     }, 
  16.     mul() { 
  17.         const arg = Array.from(arguments) 
  18.         return arg.reduce((total, num) => { 
  19.             return new Big(total).times(new Big(num)) 
  20.         }).toString() * 1 
  21.     }, 
  22.     divide() { 
  23.         const arg = Array.from(arguments) 
  24.         return arg.reduce((total, num) => { 
  25.             return new Big(total).div(new Big(num)) 
  26.         }).toString() * 1 
  27.     } 

使用

 

  1. calcFn.add(0.1, 0.2) !== 0.3 // false 

bignumber.js

  • 介紹:用于任意精度十進(jìn)制和非十進(jìn)制算術(shù)的 JavaScript 庫(kù)。
  • 特性:無依賴、包大小8 KB、兼容ECMAScript 3+可以說適用于所有瀏覽器。
  • 官網(wǎng):GitHub

 

 

 

 

https://github.com/MikeMcl/bignumber.js

使用方法類似,同上。

decimal.js

  • 介紹:為 JavaScript 提供十進(jìn)制類型的任意精度數(shù)值。
  • 特性:無依賴、包大小12.6 KB、兼容ECMAScript 3+可以說適用于所有瀏覽器。
  • 官網(wǎng):GitHub

 

 

 

 

https://github.com/MikeMcl/decimal.js

使用方法類似,同上。

Math.js

  • 介紹:用 Javascript 編寫的簡(jiǎn)單數(shù)學(xué)庫(kù),可能不維護(hù)了。
  • 特性:是一個(gè)廣泛的 JavaScript 和 Node.js 數(shù)學(xué)庫(kù)。它具有靈活的表達(dá)式解析器,支持符號(hào)計(jì)算,帶有大量?jī)?nèi)置函數(shù)和常量,并提供了一個(gè)集成的解決方案來處理不同的數(shù)據(jù)類型,如數(shù)字、大數(shù)、復(fù)數(shù)、分?jǐn)?shù)、單位和矩陣。功能強(qiáng)大且易于使用。
  • 官網(wǎng):GitHub

 

 

 

 

總結(jié)

big.js適用于大部分十進(jìn)制算術(shù)應(yīng)用程序,因?yàn)椴唤邮躈aN或Infinity作為合法值。而且不支持其他基數(shù)的值。如果項(xiàng)目中沒有非十進(jìn)制算術(shù)這非常適合用,而且關(guān)鍵是包足過小,哈哈自己造的輪子后面還是覺得庫(kù)比較香哈。

bignumber.js可能更適合金融應(yīng)用,因?yàn)槌鞘褂蒙婕俺ǖ倪\(yùn)算,否則用戶無需擔(dān)心會(huì)丟失精度。

decimal.js可能更適合更科學(xué)的應(yīng)用程序,因?yàn)樗梢愿行У靥幚矸浅P〉幕虼蟮闹怠@?,它沒有bignumber.js的限制,當(dāng)將一個(gè)小指數(shù)的值與一個(gè)大指數(shù)的值相加時(shí),bignumber.js會(huì)嘗試執(zhí)行全精度運(yùn)算,這可能會(huì)導(dǎo)致操作不可行。

如上所述,decimal.js還支持非整數(shù)冪,并增加了三角函數(shù)和exp,ln和log方法。這些添加使decimal.js明顯大于bignumber.js。

 

責(zé)任編輯:華軒 來源: 前端有道
相關(guān)推薦

2021-04-02 06:17:10

大數(shù)加減乘除數(shù)據(jù)結(jié)構(gòu)算法

2021-04-19 17:32:34

Java內(nèi)存模型

2021-09-15 13:31:44

語(yǔ)言項(xiàng)目技術(shù)棧scala

2015-06-29 09:56:08

2010-07-06 09:45:10

OracleJavaJames Gosli

2013-01-10 12:57:23

產(chǎn)品經(jīng)理App產(chǎn)品設(shè)計(jì)

2013-06-17 11:21:27

2009-03-06 09:55:48

職場(chǎng)晉升助理

2021-01-12 09:22:18

Synchronize線程開發(fā)技術(shù)

2015-07-30 09:48:38

自學(xué)編程3遍讀書法

2016-12-28 14:51:46

大數(shù)據(jù)應(yīng)用

2015-08-28 09:19:53

Web開發(fā)移動(dòng)開發(fā)

2023-02-13 10:02:31

ChatGPT人工智能

2017-07-13 17:33:18

生成對(duì)抗網(wǎng)絡(luò)GANIan Goodfel

2022-07-14 14:27:34

Javascript數(shù)字精度二進(jìn)制

2017-09-13 10:58:51

JavaScript轉(zhuǎn)換規(guī)則

2020-12-10 08:43:17

垃圾回收JVM

2023-04-27 07:41:21

Java開發(fā)技巧

2009-12-17 10:39:01

Ruby數(shù)學(xué)表達(dá)式

2022-10-13 15:51:29

C++應(yīng)用開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)