`
zccst
  • 浏览: 3322509 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

踩过的坑2-JS精确计算时的bug

阅读更多
Javascript精确计算时的bug


JS无法进行精确计算的bug

在做CRM,二代审核需求审核详情页面时。需要按比例(后端传类似0.8的小数)把用户输入的数字显示在不同的地方。
在做dubheInvest = invest * (1 - ratio);运算时发现问题。具体如下:
示例代码:

console.log( 1 - 0.8 );  //输出 0.19999999999999996
console.log( 6 * 0.7 );  //输出 4.199999999999999
console.log( 0.1 + 0.2 );  //输出 0.30000000000000004
console.log( 0.1 + 0.7 );  //输出 0.7999999999999999
console.log( 1.2 / 0.2 );  //输出 5.999999999999999
通过上面举出的例子可以看到,原生的js运算结果不一定准确,会丢失精度。
解决方案

解决方案的原理是,将浮点数乘以(扩大)10的n次方倍,把浮点数变为整数后再进行相应的运算,最后将得到的结果除以(缩小)10的n次方倍。
原理示例:

将   console.log(1-0.8);  变为 console.log((1 * 10 - 0.8 * 10) / 10); 即可得到正确的值
根据上述原理,可以封装一些方法出来解决此类问题。如下所示(Math.pow(x, y);表示求x的y次方):
  //加  
  function floatAdd(arg1,arg2){  
       var r1,r2,m;  
       try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}  
       try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}  
       m=Math.pow(10,Math.max(r1,r2));  
       return (arg1*m+arg2*m)/m;  
  }  
      
  //减  
  function floatSub(arg1,arg2){  
      var r1,r2,m,n;  
      try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}  
      try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}  
      m=Math.pow(10,Math.max(r1,r2));  
      //动态控制精度长度  
      n=(r1>=r2)?r1:r2;  
      return ((arg1*m-arg2*m)/m).toFixed(n);  
  }  
       
  //乘  
  function floatMul(arg1,arg2)   {   
      var m=0,s1=arg1.toString(),s2=arg2.toString();   
      try{m+=s1.split(".")[1].length}catch(e){}   
      try{m+=s2.split(".")[1].length}catch(e){}   
      return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);   
  }   
      
      
  //除 
  function floatDiv(arg1,arg2){   
        var t1=0,t2=0,r1,r2;   
        try{t1=arg1.toString().split(".")[1].length}catch(e){}   
        try{t2=arg2.toString().split(".")[1].length}catch(e){}   
        
        r1=Number(arg1.toString().replace(".",""));
   
        r2=Number(arg2.toString().replace(".",""));   
        return (r1/r2)*Math.pow(10,t2-t1);   
  }




如果您觉得本文的内容对您的学习有所帮助,您可以微信:
分享到:
评论
1 楼 851228082 2016-04-12  
加法和减法有问题。
比如
floatAdd(17.9,0.01)
17.909999999999997

减法在arg1*m、arg2*m这一步也会产生不精确。

不过,实现思路是正确,就是先转化为整数再计算。

这是我修改后的函数
/**
* float 加法
*/
  function floatAdd(arg1,arg2){ 
       var r1,r2,m; 
       try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
       try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
       var m =Math.pow(10,Math.max(r1,r2));
       var m1=Math.pow(10,Math.max(r1,r2)-r1); 
       var m2=Math.pow(10,Math.max(r1,r2)-r2); 
      
       var r1_integer=Number(arg1.toString().replace(".",""))*m1;
      
       var r2_integer=Number(arg2.toString().replace(".",""))*m2;  
      
      
       return (r1_integer+r2_integer)/m; 
  }
     
  //减法
  function floatSub(arg1,arg2){ 
  var r1,r2,m,n; 
      try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 
      try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 
      var m =Math.pow(10,Math.max(r1,r2));
      var m1=Math.pow(10,Math.max(r1,r2)-r1); 
      var m2=Math.pow(10,Math.max(r1,r2)-r2); 
     
      var r1_integer=Number(arg1.toString().replace(".",""))*m1;
     
      var r2_integer=Number(arg2.toString().replace(".",""))*m2;  
     
      n=(r1>=r2)?r1:r2; 
      return Number(((r1_integer-r2_integer)/m).toFixed(n)); 
     
  }


相关推荐

    解决JS浮点数(小数)计算加减乘除的BUG

    2. **使用库**:有些库如`decimal.js`或`big.js`专门用于处理高精度浮点数计算,它们可以避免JavaScript内置的浮点数精度问题。 3. **整数运算**:对于涉及金钱计算等需要精确结果的场景,可以考虑将数值转换为整数...

    chuck-bigjs:解决js计算丢失精确度的bug

    解决了js计算丢失精度的问题,稍微修改了big.js实现了连加,连减,连乘,连除。其他的请参考文档 #安装 npm的安装方式 npm install chuck-bigjs #使用方法 import Big from 'chuck-bigjs'; const number = 2; const ...

    详解js加减乘除精确计算

    JS无法进行精确计算的bug 在做CRM,二代审核需求审核详情页面时。需要按比例(后端传类似0.8的小数)把用户输入的数字显示在不同的地方。 在做dubheInvest = invest * (1 – ratio);运算时发现问题。具体如下: ...

    easyui1.4.3补丁,解决easyui-numberbox输入不了小数点bug

    这对于需要精确输入数值的场景,如财务、统计或者科学计算等,至关重要。同时,这也提高了用户体验,因为用户不再需要因为软件的bug而反复尝试输入。 在实际开发中,应用补丁通常涉及以下步骤: 1. 下载补丁文件,...

    js中浮点型运算BUG的解决方法说明.docx

    本文将详细介绍如何解决JavaScript中的浮点型运算BUG,并提供一些实用的函数来实现更精确的计算。 首先,我们要理解JavaScript中的浮点数运算误差。在计算机内部,浮点数是以二进制形式存储的,但不是所有十进制...

    Cocos2d-x游戏引擎实战开发炸弹超人二

    Cocos2d-x提供了基于Box2D的物理引擎,能够处理复杂的碰撞检测和物理模拟,确保炸弹爆炸时的精确效果。 5. **游戏逻辑** “炸弹超人二”的游戏逻辑包括炸弹的投掷、爆炸范围计算、角色死亡判断、得分系统、道具...

    js中浮点型运算BUG的解决方法说明

    曾经项目用到过的,之前在网上找到此代码,但在特定条件下除法和加法运算依然会出现BUG个人对此稍作优化 代码如下://除法函数,用来得到精确的除法结果//说明:javascript的除法结果会有误差,在两个浮点数相除的...

    JavaScript 中文转拼音实现代码 有些bug

    【JavaScript 中文转拼音实现代码 有些bug】 在开发项目时,有时会遇到需要将中文部门名称转换成拼音的需求,特别是在没有预先存储拼音数据的情况下。本文将探讨如何使用JavaScript实现这个功能,以及解决其中可能...

    JS浮点数运算结果不精确的Bug解决

    JavaScript中的浮点数运算在某些情况下可能会导致不精确的结果,这是由于其内部处理机制和IEEE-754标准的特性所致。在JavaScript中,所有的数字都以Number类型存在,本质上是按照IEEE-754标准的双精度浮点数(double...

    在Vue项目中安装配置Math.js的方法解决计算bug问题

    Math.js是一个强大的数学库,它提供了大量的数学函数、符号计算、复数运算、矩阵操作等功能,能有效解决精确计算的需求。 安装Math.js库非常简单,只需在项目的根目录下通过npm命令行工具执行以下命令: ```bash ...

    css_bug与解决方法

    标题:“css_bug与解决方法” 描述详述:本文旨在探讨并提供解决各种浏览器中的CSS bug的方法与技巧。在Web开发中,CSS(层叠样式表)是实现网页美观设计的关键技术之一,但不同浏览器对CSS的支持程度和解析方式...

    bootstrap-4.0.0-beta.3-dist

    而`popper.min.js`是Bootstrap 4引入的新依赖,用于处理定位,比如在创建弹出层时进行更精确的布局计算。 3. **核心特性**: - **栅格系统**:Bootstrap 4的栅格系统基于Flexbox,支持更灵活的布局方式,可以轻松...

    walletjs帮你轻松处理货币money的JS库

    **walletjs:轻松处理货币money的JS库** `walletjs` 是一个专为JavaScript开发者设计的轻量级库,主要用于处理货币相关的计算和格式化任务。在Web应用中,特别是涉及电子商务、金融或任何需要精确处理金钱数据的...

    详解mpvue scroll-view自动回弹bug解决方案

    在本文中,我们将深入探讨一个在使用mpvue框架开发微信小程序时遇到的特定问题:scroll-view组件在数据更新时自动回弹至顶部的bug。针对这个问题,我们将提供一种解决方案,并解释其背后的原理。 首先,我们要了解...

    slider-js:纯JavaScript滑块

    3. **定位技术**:使用`position`(static, relative, absolute, fixed)来调整滑块元素的位置,尤其是滑动项在滑动时的精确控制。 4. **响应式设计**:借助媒体查询(`media queries`),可以根据设备屏幕大小调整...

    Javascript 函数parseInt()转换时出现bug问题

    因此,使用`parseFloat()`或者使用专门处理大数和精确计算的库(如`decimal.js`)可能是更好的选择。此外,使用`toFixed(n)`可以用来固定小数点后的位数,以确保显示的数值是准确的。 总的来说,理解`parseInt()`...

    jquery ui resize 中border-box的bug修正

    此bug主要出现在使用jQuery UI的resize功能时,尤其是当页面元素应用了CSS的box-sizing: border-box属性,并与Bootstrap框架一同使用时。 首先,我们需要了解box-sizing属性的两种模式:content-box和border-box。...

    iscroll.js下载 5.2.0最新版本

    2. **高性能渲染**:iscroll.js 使用硬件加速来提升滚动的流畅性,尤其是在移动设备上,它可以充分利用GPU的计算能力,减少CPU的负载,提供更顺畅的用户体验。 3. **多平台支持**:iscroll.js 兼容多种浏览器和设备...

Global site tag (gtag.js) - Google Analytics