JavaScript 小数相加

浮点型计算会有精度丢失问题,解决思路V1版:

1、把浮点型 转换为 int整形计算 在除以 倍数

比如: 0.1+0.02=(0.1*100+0.02*100)/100

2、倍数 怎么取

小数点后的位数长度就是 倍数,可把 浮点参数 当成字符串,然后利用splic字符串处理函数来用.分割为数组,第二个数组中的字符串 就是 小数点后的 字符串,调用length就可以知道 倍数长度。

// 浮点型 加法 实现,也同时支持整形相加
// 有缺陷,1.001*1000也会有精度丢失问题
function addFloatV1(){
  // 取参数的最小值,拿到最小值计算 最小值的 小数点后的 位数 来获取倍数
  if (!arguments){
    return undefined;
  }
  var minVal = Math.min(...arguments).toString(); // 取最小值
  var minValBs = 1; // 倍数 
  if (minVal.indexOf('.') === 1) {
   var minValLength = minVal.split('.')[1].length; // 取最小值小数位数
   minValBs = Math.pow(10,minValLength);// 幂运算 计算倍数
  }
  
  // 循环参数,把参数都*100 然后再相加。
  // 循环完成后,把 整形部分的sum值 再除以 刚刚的倍数值
  var sum = 0;
  for(var i=0;i<arguments.length;i++){
    sum += arguments[i]*minValBs;
  }
  return sum/minValBs;
}

addFloatV1(1.01,1.02)

v1版本问题:1.001*1000精度丢失问题会存在,部分小数计算仍然有问题。

浮点型计算会有精度丢失问题,解决思路V2版(升级版本):

在V1版基础上,解决小数*倍数也会丢失精度问题,比如1.001*1000精度丢失

所以,最终的倍数取决于是整数的length长还是小数位数的length长,然后小数部分去掉小数点转化为整数,然后整数部分,用倍数的位数和整数的位数计算位数差值,再用整数部分乘以差值倍数来计算。最终的整数sum和在除以倍数,计算出最终结果。

// 浮点型 加法 实现,也同时支持整形相加
// 改造后
function addFloatV2(){
  // 取参数的最小值,拿到最小值计算 最小值的 小数点后的 位数 来获取倍数
  if (!arguments){
    return undefined;
  }
  var minVal = Math.min(...arguments).toString(); // 取最小值
  var minValBs = 1; // 倍数 
  var jsValLength = 0;// 计算位数
  if (minVal.indexOf('.') === 1) {
   // 取最小值小数位数
   jsValLength = minVal.split('.')[1].length>0?minVal.split('.')[1].length:0; 
  }
  var maxVal = Math.max(...arguments).toString(); // 取最大值
  if(maxVal.indexOf('.') === -1 && maxVal.length>jsValLength ){
    jsValLength = maxVal.length;
  }
  minValBs = Math.pow(10,jsValLength);// 幂运算 计算倍数
  
  // 循环参数,把参数都*100 然后再相加。
  // 循环完成后,把 整形部分的sum值 再除以 刚刚的倍数值
  var sum = 0;
  for(var i=0;i<arguments.length;i++){
    var _v = arguments[i];
    var _vStr = arguments[i].toString();
    var _vBsc = 1;
    if(_vStr.indexOf('.') === 1) {
       var _vInt = parseInt(_vStr.replace('.',''));
       // 取最小值小数位数
       var _vLength= _vStr.split('.')[1].length>0?_vStr.split('.')[1].length:0;
       // 倍数差,就是当前浮点数要乘以的倍
       var _vBs = Math.pow(10,jsValLength - _vLength); 
       sum+=_vInt *_vBs;
    } else {
       var _vLength = _vStr.length>1?_vStr.length:0;
       // 倍数差,就是当前浮点数要乘以的倍
       var _vBs = Math.pow(10,jsValLength);
       sum += _v*_vBs;
    }
  }
  return sum/minValBs;
}

addFloatV2(1.001,2.0)

展示结果:目前测试了几个都正常,如有问题,请反馈

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值