前端小數(shù)的精度問題
0.1 + 0.2 !== 0.3
前言:因?yàn)闅v史的遺留問題趟薄,前端對浮點(diǎn)型數(shù)據(jù)的處理一直不是很精確掉奄,因此需要通過一些方法進(jìn)行處理
可以新建一個utils目錄下新建.js的文件
- 多個數(shù)據(jù)的累加操作葡缰,傳遞一個數(shù)組即可
// 小數(shù)相加精度計算 arr: [1.11, 2.333, 4.2333],需要多個值累計的操作蟹漓,調(diào)用的時候傳遞進(jìn)去一個數(shù)組索抓。
// 原理:對數(shù)據(jù)進(jìn)行遍歷統(tǒng)一先乘以一個較大的整數(shù)進(jìn)行累加碳蛋,完成后對得到的數(shù)據(jù)進(jìn)行除即可解決
export const decimal_NUM = (arr) => {
let initial = 0
arr.forEach(c => {
c = Number(c) * 100000000
initial = initial + Number(c)
})
return initial / 100000000
}
- 小數(shù)相減的處理,傳遞兩個參數(shù)即可
// 小數(shù)相減 5.9 - 3.1
export const Number_SubAll = (arg1, arg2) => {
var re1, re2, m, n
try {
re1 = arg1.toString().split('.')[1].length
} catch (e) {
re1 = 0
}
try {
re2 = arg2.toString().split('.')[1].length
} catch (e) {
re2 = 0
}
m = Math.pow(10, Math.max(re1, re2))
n = (re1 >= re2) ? re1 : re2
return ((arg1 * m - arg2 * m) / m).toFixed(n)
}
- 小數(shù)相除保留小數(shù)點(diǎn)位數(shù)胚泌,傳遞三個參數(shù)
// 除數(shù),被除數(shù)肃弟, 保留的小數(shù)點(diǎn)后的位數(shù)
export const Number_DIV = (arg1, arg2, digit) => {
let t1 = 0
let t2 = 0
let r1 = null
let r2 = null
try { t1 = arg1.toString().split('.')[1].length } catch (e) { e }
try { t2 = arg2.toString().split('.')[1].length } catch (e) { e }
r1 = Number(arg1.toString().replace('.', ''))
r2 = Number(arg2.toString().replace('.', ''))
const result = ((r1 / r2) * Math.pow(10, t2 - t1)).toString()
let result2 = result.split('.')[1]
result2 = result2.substring(0, digit > result2.length ? result2.length : digit)
return Number(result.split('.')[0] + '.' + result2)
}
- 小數(shù)除法玷室,不保留小數(shù)點(diǎn)位數(shù),傳遞兩個數(shù)據(jù)
// 除數(shù)笤受,被除數(shù)穷缤, 保留的小數(shù)點(diǎn)后的位數(shù)
export const Number_Div = (data1, data2) => {
let t1 = 0
let t2 = 0
let r1 = null
let r2 = null
// 獲取每個參數(shù)的小數(shù)的位數(shù)
try { t1 = data1.toString().split('.')[1].length } catch (e) { e }
try { t2 = data2.toString().split('.')[1].length } catch (e) { e }
// 把所有參數(shù)的小數(shù)點(diǎn)去掉轉(zhuǎn)為整數(shù)
r1 = Number(data1.toString().replace('.', ''))
r2 = Number(data2.toString().replace('.', ''))
return (r1 / r2) * Math.pow(10, t2 - t1)
}
// 如果想控制小數(shù)點(diǎn)的位數(shù)可以通過.toFixed(數(shù)位)進(jìn)行處理
// let numbers = Number_Div(除數(shù), 被除數(shù)).toFixed(保留小數(shù)位數(shù))
- 小數(shù)相乘,傳遞兩個參數(shù)
// 小數(shù)相乘
export const Number_Mul = (arg1, arg2) => {
var m = 0
var s1 = arg1.toString()
var s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) { e }
try {
m += s2.split('.')[1].length
} catch (e) { e }
return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}