详解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 相关文章推荐
JQuery中使用Ajax赋值给全局变量异常的解决方法
Jan 10 Javascript
详谈JavaScript内存泄漏
Nov 14 Javascript
node.js抓取并分析网页内容有无特殊内容的js文件
Nov 17 Javascript
jquery+css3实现会动的小圆圈效果
Jan 27 Javascript
ionic实现可滑动的tab选项卡切换效果
Apr 15 Javascript
jQuery EasyUI 获取tabs的实例解析
Dec 06 Javascript
JS验证字符串功能
Feb 22 Javascript
javascript实现多张图片左右无缝滚动效果
Mar 22 Javascript
详解node.js平台下Express的session与cookie模块包的配置
Apr 26 Javascript
JS中Safari浏览器中的Date
Jul 17 Javascript
js实现会跳动的日历效果(完整实例)
Oct 18 Javascript
JavaScript实现外溢动态爱心的效果的示例代码
Mar 21 Javascript
实现隔行换色效果的两种方式【实用】
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&mysql(五)
2006/10/09 PHP
CodeIgniter CLI模式简介
2014/06/17 PHP
PHP读书笔记_运算符详解
2016/07/01 PHP
常用PHP封装分页工具类
2017/01/14 PHP
JS延迟加载(setTimeout) JS最后加载
2010/07/15 Javascript
基于PHP+Jquery制作的可编辑的表格的代码
2011/04/10 Javascript
JS获取当前网址、主机地址项目根路径
2013/11/19 Javascript
动态显示可输入的字数提示还可以输入的字数
2014/04/01 Javascript
javascript格式化指定日期对象的方法
2015/04/21 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
js添加事件的通用方法推荐
2016/05/15 Javascript
JS框架之vue.js(深入三:组件1)
2016/09/29 Javascript
JavaScript 深层克隆对象详解及实例
2016/11/03 Javascript
JS检测数组类型的方法小结
2017/03/14 Javascript
vue学习笔记之指令v-text && v-html && v-bind详解
2017/05/12 Javascript
基于hover的用法实例(推荐)
2017/07/04 Javascript
vue中如何实现pdf文件预览的方法
2018/07/12 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
2018/08/07 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
Element Collapse 折叠面板的使用方法
2020/07/26 Javascript
swiper4实现移动端导航栏tab滑动切换
2020/10/16 Javascript
Python常用小技巧总结
2015/06/01 Python
Python实现修改IE注册表功能示例
2018/05/10 Python
详解Python的循环结构知识点
2019/05/20 Python
python 画出使用分类器得到的决策边界
2019/08/21 Python
django rest framework 自定义返回方式
2020/07/12 Python
python 从list中随机取值的方法
2020/11/16 Python
python 数据类型强制转换的总结
2021/01/25 Python
python中numpy.empty()函数实例讲解
2021/02/05 Python
Philosophy美国官网:美国美容品牌
2016/08/15 全球购物
Mountain Hardwear官网:攀岩服装和户外装备
2019/09/26 全球购物
俄罗斯品牌服装在线商店:VIPAVENUE
2020/08/10 全球购物
Ref与out有什么不同
2012/11/24 面试题
星级党支部申报材料
2014/05/31 职场文书
单位委托书怎么写
2014/09/21 职场文书
领导干部整治奢华浪费之风思想汇报
2014/10/07 职场文书