tags: ‘js’
categories: ‘js’
js计算丢失精度问题(加法、减法、乘法、除法)
方法一: 原型
// 加法
Number.prototype.add = function(arg){
var r1,r2,m;
try{
r1=this.toString().split(".")[1].length
}catch(e){
r1=0
}
try{
r2=arg.toString().split(".")[1].length
}catch(e){
r2=0
}
m = Math.pow(10,Math.max(r1,r2));
return Math.round(this*m+arg*m)/m
}
0.1+0.2 // 0.30000000000000004
0.1.add(0.2) // 0.3
// 减法
Number.prototype.sub = function (arg){
return this.add(-arg);
}
0.3-0.1 // 0.19999999999999998
0.3.sub(0.1) // 0.2
5000.02.sub(905.8) // 4094.22
// 乘法
Number.prototype.mul = function (arg){
var m=0,s1=this.toString(),s2=arg.toString();
try{
m+=s1.split(".")[1].length
}catch(e){}
try{
m+=s2.split(".")[1].length
}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
0.00035.mul(100) // 0.035
// 除法
Number.prototype.div = function (arg){
var t1=0,t2=0,r1,r2;
try{
t1=this.toString().split(".")[1].length
}catch(e){}
try{
t2=arg.toString().split(".")[1].length
}catch(e){}
with(Math){
r1=Number(this.toString().replace(".",""))
r2=Number(arg.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
方法二: 将小数化成整数后再作运算
/**
* 加法运算,避免数据相加小数点后产生多位数和计算精度损失。
*
* @param num1加数1 | num2加数2
*/
function numAdd(num1, num2) {
var baseNum, baseNum1, baseNum2;
try {
baseNum1 = num1.toString().split(".")[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split(".")[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
return (num1 * baseNum + num2 * baseNum) / baseNum;
};
/**
* 加法运算,避免数据相减小数点后产生多位数和计算精度损失。
*
* @param num1被减数 | num2减数
*/
function numSub(num1, num2) {
var baseNum, baseNum1, baseNum2;
var precision;// 精度
try {
baseNum1 = num1.toString().split(".")[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split(".")[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;
return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
};
/**
* 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。
*
* @param num1被乘数 | num2乘数
*/
function numMulti(num1, num2) {
var baseNum = 0;
try {
baseNum += num1.toString().split(".")[1].length;
} catch (e) {
}
try {
baseNum += num2.toString().split(".")[1].length;
} catch (e) {
}
return Number(num1.toString().replace(".", "")) * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum);
};
/**
* 除法运算,避免数据相除小数点后产生多位数和计算精度损失。
*
* @param num1被除数 | num2除数
*/
function numDiv(num1, num2) {
var baseNum1 = 0, baseNum2 = 0;
var baseNum3, baseNum4;
try {
baseNum1 = num1.toString().split(".")[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split(".")[1].length;
} catch (e) {
baseNum2 = 0;
}
with (Math) {
baseNum3 = Number(num1.toString().replace(".", ""));
baseNum4 = Number(num2.toString().replace(".", ""));
return (baseNum3 / baseNum4) * pow(10, baseNum2 - baseNum1);
}
};
参考文献
js 计算精度问题,及解决办法
JS 四则运算(加减乘除小数运算)避免损失精度