javaScript 小数计算精度丢失

情景举例 : 有天对象问我一个问题,说前端计算有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开干

一开始我写的版本

image

isFinite用来判断是否数字时又遇到坑了 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;

  }

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容