情景举例 : 有天对象问我一个问题,说前端计算有Bug,根据她的描述我抱着怀疑的态度去控制台试了试,写了一个220 /1.1,按下enter键一看,还真的有问题,计算结果居然是199.999999999997
image为什么会是这样呢 ?抱着疑惑去各大知名网站搜了搜原因,大概就是说js运算
image好吧 知道了问题的原因就想办法去解决他,既然小数转整数过程出现了问题,那就不能让计算中出现小数呀,于是乎就想到了把各种小数小数问题10来转化为最小整数计算,例如1.1 转化为最小整数就是1.1 * 1 * 10 = 11,220/1.1也就可以转化为:
220 * 1 * 10 / 1.1 * 1 * 10 = 200
ok, It`s beautiful ! 我们找到了解决的思路,对于运算我们涉及到加减乘除(+-*/),那干脆封装一个脚本来处理运算好了,emmmm开干
一开始我写的版本
imageisFinite用来判断是否数字时又遇到坑了 isFinite(true) isFinite(null) isFinite('')也会返回true
当我正想着用正则去校验数字时,对象说用typeOf()就可以了,我试了试还真是好使,都说写一个功能有多种方法,那当然是代码越简洁越好喽,学习长路慢慢而路途遥远,下面附上代码:
/**
-
计算,处理精确度丢失
-
@param {Number} arg1
-
@param {Number} arg2
-
@param {String} operator
*/
export function calculationRender(arg1, arg2, operator) {
if (operator === '/' && arg2 === 0) return;
if (typeof (arg1) === 'number' && typeof (arg2) === 'number') {
const precision1 = arg1.toString().split('.')[1] ? arg1.toString().split('.')[1].length : 0;
const precision2 = arg2.toString().split('.')[1] ? arg2.toString().split('.')[1].length : 0;
let maxPrecision = Math.max(precision1, precision2);
maxPrecision = 10 ** maxPrecision;
const num1 = arg1 * maxPrecision;
const num2 = arg2 * maxPrecision;
switch (operator) {
case '+':
return (num1 + num2) / maxPrecision;
case '-':
return (num1 - num2) / maxPrecision;
case '*':
return (num1 * num2) / (maxPrecision*maxPrecision);
case '/':
return num1 / num2;
default:
break;
}
}
}
网友评论