js计算精度问题
1. 封装js文件 【文件名calculation】
/**
* 解决js计算的精度问题
*/
const fn = {
countDecimals(num) {
let len = 0
try {
num = Number(num)
let str = num.toString().toUpperCase()
if (str.split('E').length === 2) { // scientific notation
let isDecimal = false
if (str.split('.').length === 2) {
str = str.split('.')[1]
if (parseInt(str.split('E')[0]) !== 0) {
isDecimal = true
}
}
let x = str.split('E')
if (isDecimal) {
len = x[0].length
}
len -= parseInt(x[1])
} else if (str.split('.').length === 2) { // decimal
if (parseInt(str.split('.')[1]) !== 0) {
len = str.split('.')[1].length
}
}
} catch (e) {
throw e
} finally {
if (isNaN(len) || len < 0) {
len = 0
}
// eslint-disable-next-line no-unsafe-finally
return len
}
},
convertToInt(num) {
num = Number(num)
let newNum = num
let times = this.countDecimals(num)
let tempNum = num.toString().toUpperCase()
if (tempNum.split('E').length === 2) {
newNum = Math.round(num * Math.pow(10, times))
} else {
newNum = Number(tempNum.replace('.', ''))
}
return newNum
},
getCorrectResult(type, num1, num2, result) {
let tempResult = 0
switch (type) {
case 'add':
tempResult = num1 + num2
break
case 'sub':
tempResult = num1 - num2
break
case 'div':
tempResult = num1 / num2
break
case 'mul':
tempResult = num1 * num2
break
}
if (Math.abs(result - tempResult) > 1) {
return Number(tempResult)
}
return Number(result)
}
}
const calculation = {
// 加法
add(num1, num2) {
num1 = Number(num1)
num2 = Number(num2)
let dec1, dec2, times
try { dec1 = fn.countDecimals(num1) + 1 } catch (e) { dec1 = 0 }
try { dec2 = fn.countDecimals(num2) + 1 } catch (e) { dec2 = 0 }
times = Math.pow(10, Math.max(dec1, dec2))
// let result = (num1 * times + num2 * times) / times
let result = (this.mul(num1, times) + this.mul(num2, times)) / times
return fn.getCorrectResult('add', num1, num2, result)
// return result
},
// 减法
sub(num1, num2) {
num1 = Number(num1)
num2 = Number(num2)
let dec1, dec2, times
try { dec1 = fn.countDecimals(num1) + 1 } catch (e) { dec1 = 0 }
try { dec2 = fn.countDecimals(num2) + 1 } catch (e) { dec2 = 0 }
times = Math.pow(10, Math.max(dec1, dec2))
// let result = Number(((num1 * times - num2 * times) / times)
let result = Number((this.mul(num1, times) - this.mul(num2, times)) / times)
return fn.getCorrectResult('sub', num1, num2, result)
// return result
},
// 乘法
mul(num1, num2) {
num1 = Number(num1)
num2 = Number(num2)
let times = 0
let s1 = num1.toString()
let s2 = num2.toString()
try { times += fn.countDecimals(s1) } catch (e) { }
try { times += fn.countDecimals(s2) } catch (e) { }
let result = fn.convertToInt(s1) * fn.convertToInt(s2) / Math.pow(10, times)
return fn.getCorrectResult('mul', num1, num2, result)
// return result
},
// 除法
div(num1, num2) {
num1 = Number(num1)
num2 = Number(num2)
let t1 = 0
let t2 = 0
let dec1, dec2
try { t1 = fn.countDecimals(num1) } catch (e) { }
try { t2 = fn.countDecimals(num2) } catch (e) { }
dec1 = fn.convertToInt(num1)
dec2 = fn.convertToInt(num2)
let result = this.mul((dec1 / dec2), Math.pow(10, t2 - t1))
return fn.getCorrectResult('div', num1, num2, result)
// return result
}
}
export default calculation
2. 使用
1. 引入
import calculation from "@/api/calculation"
2. 使用
// 加法
calculation.add(参数一,参数二)
// 减法
calculation.sub(参数一,参数二)
// 乘法
calculation.mul(参数一,参数二)
// 除法
calculation.div(参数一,参数二)