详解JS-- 浮点数运算处理


Posted in Javascript onNovember 28, 2016

一. 问题描述

最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如:

0.1+0.2 == 0.30000000000000004
 
0.1 + 0.7 == 0.7999999999999999
 
7*0.8 == 5.6000000000000005
 
5.6/7 == 0.7999999999999999

二.解决方案

 

JS运算后都会有很小的误差. 不像.Net或者Java那样准确. 主要是JS重点不在运算上面,可是有时候项目一定要用到.想了一下大概有两种解决方案

A 方案一:

运算结果保留2-3位小数位数. 前端界面一般用到的运算比较少。精度要求不会太高。 所以取2位小数位即可。

B. 方案二:

将小数位数转换为整数运算. 譬如:

0.1+0.2 =》 (1+2)/10 == 0.3
 
0.1 + 0.7 =》 (1+7)/10 == 0.8
 
7*0.8 == (7*8)/10 == 5.6
 
5.6/7 == (56/7)/10 == 0.1

为了方便调用. 所以我们可以提取一个公共的方法出来.譬如下面的JSMath库,JSMath重写了加减乘除. 会先将参数转换为整数再运算JSMath(参数1).操作(参数2)

参数1和参数2分别就是运算的第一个Number和第二个Number. 计算后通过Value属性获取值.

(function() {
 
  var JSMath = function() {
    return this;
  }
 
  JSMath.prototype.from = function(value) {
 
    // 支持JSMath参数传递主要是用于嵌套的调用
    if ((typeof(value) == 'object') && (value.value != undefined)) {
      this.value = value.value;
    } else {
      this.value = value;
    }
    return this;
  }
 
  // 加法
  JSMath.prototype.add = function(value) {
    var thisValueString = this.value.toString();
    var valueString = value.toString();
    var timesCount1 = 0;
    var timesCount2 = 0;
    if (thisValueString.indexOf('.') > 0) {
      timesCount1 = thisValueString.split('.')[1].length;
    }
    if (valueString.indexOf('.') > 0) {
      timesCount2 = valueString.split('.')[1].length;
    }
    var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
    this.value = (Math.pow(10, maxtimeCount) * this.value + Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount);
    return this;
  }
 
 // 减法
  JSMath.prototype.sub = function(value) {
    var thisValueString = this.value.toString();
    var valueString = value.toString();
    var timesCount1 = 0;
    var timesCount2 = 0;
    if (thisValueString.indexOf('.') > 0) {
      timesCount1 = thisValueString.split('.')[1].length;
    }
    if (valueString.indexOf('.') > 0) {
      timesCount2 = valueString.split('.')[1].length;
    }
    var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
    this.value = (Math.pow(10, maxtimeCount) * this.value - Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount);
    return this;
  }
 
  // 除法

  JSMath.prototype.div = function(value) {
    var thisValueString = this.value.toString();
    var valueString = value.toString();
    var timesCount1 = 0;
    var timesCount2 = 0;
    if (thisValueString.indexOf('.') > 0) {
      timesCount1 = thisValueString.split('.')[1].length;
    }
    if (valueString.indexOf('.') > 0) {
      timesCount2 = valueString.split('.')[1].length;
    }
    var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
    this.value = ((Math.pow(10, maxtimeCount) * this.value) / (Math.pow(10, maxtimeCount) * value));
    return this;
  }
 
  // 乘法
  JSMath.prototype.times = function(value) {
 
    var thisValueString = this.value.toString();
    var valueString = value.toString();
    var timesCount1 = 0;
    var timesCount2 = 0;
    if (thisValueString.indexOf('.') > 0) {
      timesCount1 = thisValueString.split('.')[1].length;
    }
    if (valueString.indexOf('.') > 0) {
      timesCount2 = valueString.split('.')[1].length;
    }
    var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
    this.value = (Math.pow(10, maxtimeCount) * this.value * Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount * 2);
    return this;
  }
 
  if (window.JSMath == undefined) {
    window.JSMath = function(value) {
      var result = new JSMath();
      result.from(value);
      return result;
    }
  }
})()

B1.基本运算

0.1+0.2
=> JSMath(0.1).add(0.2).value == 0.3
 
7+0.8
=> JSMath(7).times(0.8).value == 5.6
 
5.6/7
=> JSMath(5.6).div(7).value = 0.8

B2.多目运算

0.05 + 0.05 + 0.2
=> JSMath(JSMath(0.05).add(0.05)).add(0.2).value == 0.3
 
(5+0.6)/7
=> JSMath(JSMath(5).add(0.6)).div(7).value == 0.8

三.小总结

上面自己自己暂时知道的一些解决方案.不太清楚是否有开源的更可靠的三方库来解决这个问题。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE6与IE7中,innerHTML获取param的区别
Mar 15 Javascript
Ext 今日学习总结
Sep 19 Javascript
JavaScript实现页面实时显示当前时间的简单实例
Jul 20 Javascript
JS根据生日算年龄的方法
May 05 Javascript
javascript动画算法实例分析
Jul 31 Javascript
JavaScript获取function所有参数名的方法
Oct 30 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
Jul 15 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
Dec 24 Javascript
vue中父子组件注意事项,传值及slot应用技巧
May 09 Javascript
vue父组件给子组件的组件传值provide inject的方法
Oct 23 Javascript
element-ui中el-upload多文件一次性上传的实现
Dec 02 Javascript
vue实现可移动的悬浮按钮
Mar 04 Vue.js
实现隔行换色效果的两种方式【实用】
Nov 27 #Javascript
javascript实现无法关闭的弹框
Nov 27 #Javascript
js格式化时间的简单实例
Nov 27 #Javascript
浅谈jquery页面初始化的4种方式
Nov 27 #Javascript
js实现页面刷新滚动条位置不变
Nov 27 #Javascript
Javascrip实现文字跳动特效
Nov 27 #Javascript
JavaScript 监控微信浏览器且自带返回按钮时间
Nov 27 #Javascript
You might like
用PHP动态创建Flash动画
2006/10/09 PHP
PHP学习之PHP变量
2006/10/09 PHP
WordPress中创建用户角色的相关PHP函数使用详解
2015/12/25 PHP
joomla组件开发入门教程
2016/05/04 PHP
PHP赋值的内部是如何跑的详解
2019/01/13 PHP
Javascript 构造函数,公有,私有特权和静态成员定义方法
2009/11/30 Javascript
javascript判断ie浏览器6/7版本加载不同样式表的实现代码
2011/12/26 Javascript
js判断上传文件后缀名是否合法
2016/01/28 Javascript
基于JS代码实现实时显示系统时间
2016/06/16 Javascript
Jquery组件easyUi实现选项卡切换示例
2016/08/23 Javascript
Angular.js之作用域scope'@','=','&'实例详解
2017/02/28 Javascript
jQuery实现表单动态添加与删除数据操作示例
2018/07/03 jQuery
详解vue-cli 3.0 build包太大导致首屏过长的解决方案
2018/11/10 Javascript
详解Vue-axios 设置请求头问题
2018/12/06 Javascript
vue 实现单选框设置默认选中值
2019/11/07 Javascript
npx create-react-app xxx创建项目报错的解决办法
2020/02/17 Javascript
[06:21]完美世界亚洲区首席发行官竺琦TI3采访
2013/08/26 DOTA
浅析Python中signal包的使用
2015/11/13 Python
python使用arcpy.mapping模块批量出图
2017/03/06 Python
详解Python核心对象类型字符串
2018/02/11 Python
pthon贪吃蛇游戏详细代码
2019/01/27 Python
Python3标准库总结
2019/02/19 Python
python命令行工具Click快速掌握
2019/07/04 Python
基于python读取.mat文件并取出信息
2019/12/16 Python
keras实现多GPU或指定GPU的使用介绍
2020/06/17 Python
HTML5+CSS3 实现灵动的动画 TAB 切换效果(DEMO)
2017/09/15 HTML / CSS
澳大利亚制造的羊皮靴:Original UGG Boots
2017/11/13 全球购物
全球最大的中文旅行网站:去哪儿网
2017/11/16 全球购物
应届毕业生应聘自荐信范文
2014/02/26 职场文书
小学数学课后反思
2014/04/23 职场文书
个人反四风对照检查材料思想汇报
2014/09/23 职场文书
《改造我们的学习》心得体会
2014/11/07 职场文书
2015年爱牙日活动总结
2015/02/05 职场文书
2015年校本培训工作总结
2015/07/24 职场文书
告诉你一个秘密:富人致富的五大优点
2019/07/11 职场文书