精确加减乘除
/**
* 解决 js 浮点运算时精度丢失问题
* plus 加
* minus 减
* times 乘
* divide 除
*/
/**
* 把错误的数据转正
* strip(0.09999999999999998)=0.1
*/
function strip(num, precision = 12) {
return +parseFloat(num.toPrecision(precision))
}
/**
* Return digits length of a number
* @param {*number} num Input number
*/
function digitLength(num) {
// Get digit length of e
const eSplit = num.toString().split(/[eE]/)
const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0)
return len > 0 ? len : 0
}
/**
* 把小数转成整数,支持科学计数法。如果是小数则放大成整数
* @param {*number} num 输入数
*/
function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''))
}
const dLen = digitLength(num)
return dLen > 0 ? strip(num * Math.pow(10, dLen)) : num
}
/**
* 精确加法
*/
Math.plus = function (num1, num2, ...others) {
if (others.length > 0) {
return Math.plus(Math.plus(num1, num2), others[0], ...others.slice(1))
}
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)))
return (Math.times(num1, baseNum) + Math.times(num2, baseNum)) / baseNum
}
/**
* 精确减法
*/
Math.minus = function (num1, num2, ...others) {
if (others.length > 0) {
return Math.minus(Math.minus(num1, num2), others[0], ...others.slice(1))
}
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)))
return (Math.times(num1, baseNum) - Math.times(num2, baseNum)) / baseNum
}
/**
* 精确乘法
*/
Math.times = function (num1, num2, ...others) {
if (others.length > 0) {
return Math.times(Math.times(num1, num2), others[0], ...others.slice(1))
}
const num1Changed = float2Fixed(num1)
const num2Changed = float2Fixed(num2)
const baseNum = digitLength(num1) + digitLength(num2)
const leftValue = num1Changed * num2Changed
return leftValue / Math.pow(10, baseNum)
}
/**
* 精确除法
*/
Math.divide = function (num1, num2, ...others) {
if (others.length > 0) {
return Math.divide(Math.divide(num1, num2), others[0], ...others.slice(1))
}
const num1Changed = float2Fixed(num1)
const num2Changed = float2Fixed(num2)
return Math.times(num1Changed / num2Changed, Math.pow(10, digitLength(num2) - digitLength(num1)))
}

浙公网安备 33010602011771号