JavaScript 小数相加

news/2024/7/19 15:39:37 标签: javascript, js, 前端

浮点型计算会有精度丢失问题,解决思路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)

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

 


http://www.niftyadmin.cn/n/1867584.html

相关文章

html是什么的理解

文章中我说两部分&#xff0c;1部分官方解释 2部分说说自己理解。 官方标准解释&#xff1a; HTML的全称为HyperText Markup Language&#xff0c;也就是超文本标记语 言。HTML文本是由HTML命令组成的描述性文本&#xff0c;HTML命令可以说 明文字、图形、动画、声音、表格、超…

Emeditor 删除一行某个字符之前所有内容

示例&#xff1a;一行中前有 数字.XXX 需求&#xff1a;删除掉XXX前的内容 操作&#xff1a;使用Emeditor的查询替换 正则表达式&#xff0c;查找^.\. 替换为空 参考内容&#xff1a; Emeditor 常用的正则表达式 - dzqabc - 博客园Emeditor 目前来说是我个人感觉非常不错的一…

win10家庭版设置本地策略组

win10家庭版没有本次策略组&#xff0c;在远程桌面时、会报某些错误&#xff0c;需要在本次策略组配置些东西。 本地策略组添加步骤&#xff1a; 1、新建个文件夹&#xff0c;cmd进入新建文件夹 dos命令 回车 目的在文件夹中&#xff0c;新建一个 gpedit.cmd 的文件 2、文件…

我的学习清单

一、css学习 布局学习&#xff08;2-3套课程学习&#xff09; less sass 二、vue系列学习 axios vue router vuex webpack node学习 npm 命令 三、Java学习 springboot springmvc 课外学习&#xff1a; 沙雕动画 摄影技术 素描学习画画 自考&#xff1a; 英语…

1.mac M1 Java 开发环境的安装与配置

1.首先我们打开谷歌浏览器复制下面的网址安装jdk&#xff1a; Java Download | Java 7, Java 8, Java 11, Java 13, Java 15, Java 17, Java 19 - Linux, Windows and macOShttps://www.azul.com/downloads/?packagejdk#zulu 2.我们翻到最下面去选择我们需要的版本&#xff…

MYSQL使用binlog日志恢复数据

本教程目的在于&#xff0c;你的MYSQL采用了binlog日志&#xff0c;且产生了binlog日志文件&#xff0c;使用日志文件恢复数据。 步骤一、找到要恢复数据的binlog文件 怎么找&#xff1f;使用命令&#xff1a;show variables like %log_bin%; 如下图&#xff1a;这个路径就是…

Vue 知识点:列表排序

Vue 知识点&#xff1a;列表排序 <div id"root"><h2>人员列表</h2><input type"text" placeholder"请输入名字" v-model"keyword"/><button click"sortType 2">年龄升序</button><…

Vue 知识点:Vue.set()方法

Vue 知识点&#xff1a;Vue.set()方法 <div id"root"><h1>学校信息</h1><h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{address}}</h2><hr/><h1>学生信息</h1><button click&qu…