在项目中出现的问题
加法
0.1+0.2 = 0.30000000000000004
减法
1-0.8 = 0.19999999999999996
乘法
0.6*0.75 = 0.44999999999999996
9.2*100 = 919.9999999999999
除法
1.2/0.2 = 5.999999999999999
出现问题的大致原因是 Number类型运算都需要先将十进制转二进制,但小数点后的位数转二进制会出现无限循环的问题,只能舍0入1,所以会出现小数点丢失问题。
感兴趣的可以自己研究,在这里只是简单阐述下。
解决办法
/**
* 小数精确度处理
* @param {number} num1 数字
* @param {number} num2 数字
* @param {string} symbol +-*\/符号
*/
function amendNumber(num1, num2, symbol) {
let result
let str1Length = 0
let str2Length = 0
// 解决整数没有小数点方法
try {
str1Length = (num1 + '').split('.')[1].length
} catch (e) {
//
}
try {
str2Length = (num2 + '').split('.')[1].length
} catch (error) {
//
}
const step = Math.pow(10, Math.max(str1Length, str2Length))
const n1 = Number((num1 * step).toFixed()) // 转换成整数 0.0012 * 100000000 = 119999.99999999999
const n2 = Number((num2 * step).toFixed()) // 转换成整数 0.0012 * 100000000 = 119999.99999999999
switch (symbol) {
case '+':
result = (n1 + n2) / step
break
case '-':
result = (n1 - n2) / step
break
case '*':
result = (n1 * n2) / (step * step)
break
case '/':
result = n1 / n2
break
default:
break
}
return result
}
/**
* 加法
* @param {number} num1
* @param {number} num2
* @returns
*/
function add(num1, num2) {
return amendNumber(num1, num2, '+')
}
/**
* 减法
* @param {number} num1
* @param {number} num2
* @returns
*/
function subtract(num1, num2) {
return amendNumber(num1, num2, '-')
}
/**
* 乘法
* @param {number} num1
* @param {number} num2
* @returns
*/
function multiply(num1, num2) {
return amendNumber(num1, num2, '*')
}
/**
* 除法
* @param {number} num1
* @param {number} num2
* @param {number} fractionDigits 精确小数几位
* @returns
*/
function divide(num1, num2, fractionDigits) {
const value = amendNumber(num1, num2, '/')
if (!isNaN(fractionDigits) && typeof fractionDigits === 'number') {
return value.toFixed(fractionDigits) - 0
} else {
return value
}
}
//测试
console.log('加法:', add('a', 0.2)) // NaN
console.log('加法:', add(NaN, 0.2)) // NaN
console.log('加法:', add('0.1', 0.2)) // 0.3
console.log('减法:', subtract(1, 0.8)) // 0.2
console.log('乘法:', multiply(0.6, 0.75)) // 0.45
console.log('乘法:', multiply(9.2, 100)) // 920
console.log('除法:', divide(1.2, 0.2)) // 6
console.log('除法:', divide(1, 3)) // 0.3333333333333333
console.log('除法:', divide(1, 3, 3)) // 0.333