//
// 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//
//
/**
* 加法函数,用来得到精确的加法结果
* @param {*} arg1
* @param {*} arg2
* @returns arg1加上arg2的精确结果
*/
export function accAdd(arg1, arg2) {
var r1, r2, m
try { r1 = arg1.toString().split('.')[1].length } catch (e) { r1 = 0 }
try { r2 = arg2.toString().split('.')[1].length } catch (e) { r2 = 0 }
m = Math.pow(10, Math.max(r1, r2))
return parseFloat(((arg1 * m + arg2 * m) / m).toFixed(Math.max(r1, r2)))
}
/**
* 减法函数,用来得到精确的加法结果
* @param {*} arg1
* @param {*} arg2
* @returns arg1减去arg2的精确结果
*/
export function accSub(arg1, arg2) {
var r1, r2, m, n
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
// last modify by deeka
// 动态控制精度长度
n = (r1 >= r2) ? r1 : r2
return ((arg1 * m - arg2 * m) / m).toFixed(n)
}
/**
* 除法函数,用来得到精确的除法结果
* @param {*} arg1
* @param {*} arg2
* @returns
*/
export function accDiv(arg1, arg2) {
var t1 = 0; var t2 = 0; var r1; var r2
try {
t1 = arg1.toString().split('.')[1].length
} catch (e) {
t1 = 0
}
try {
t2 = arg2.toString().split('.')[1].length
} catch (e) {
t2 = 0
}
r1 = Number(arg1.toString().replace('.', ''))
r2 = Number(arg2.toString().replace('.', ''))
return (r1 / r2) * Math.pow(10, t2 - t1)
}
/**
* 乘法函数,用来得到精确的乘法结果
* @param {*} arg1
* @param {*} arg2
* @returns arg1乘以arg2的精确结果
*/
export function accMul(arg1, arg2) {
var m = 0
var s1 = arg1.toString()
var s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) {
m = 0
}
try {
m += s2.split('.')[1].length
} catch (e) {
m = 0
}
return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}
// 在你要用的地方包含这些函数,然后调用它来计算就可以了。
// 比如你要计算:7*0.8 ,则改成 (7).mul(8)
// 其它运算类似,就可以得到比较精确的结果。
// 给Number类型增加一个mul方法,调用起来更加方便。
// eslint-disable-next-line no-extend-native
Number.prototype.accAdd = function(arg) {
return accAdd(arg, this)
}
// eslint-disable-next-line no-extend-native
Number.prototype.accSub = function(arg) {
return accSub(arg, this)
}
// eslint-disable-next-line no-extend-native
Number.prototype.accMul = function(arg) {
return accMul(arg, this)
}
// eslint-disable-next-line no-extend-native
Number.prototype.accDiv = function(arg) {
return accDiv(this, arg)
}
export default {
accAdd,
accSub,
accMul,
accDiv
}
使用
import { accSub, accAdd } from '@/utils/acc.js'