当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 详解JS-- 浮点数运算处理

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

一. 问题描述

最近在做一个项目,页面上会存在一些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

三.小总结

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网