下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

web前端:js精准计算

作者: fingersnow     来源: https://www.cnblogs.com/zhijiancanxue/archive/2020/03/16/125点击数:671发布时间: 2020-03-25 12:03:57

标签: 编程语言js计算机

Web开发

  当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。计算机中的二进制则是一个非常微小的开关,用1来表示“开”,0来表示“关”。

  js精准计算

  varnumA=0.1;

  varnumB=0.2;

  alert(numA+numB);

  0.1+0.2=0.30000000000000004。

  计算精度误差问题(和二进制相关)。

  对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在C++/C#/java这些语言中已经封装好了方法来避免精度的问题,而Javascript是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,所以精度误差的问题就显得格外突出。

  我们先把0.1和0.2转换成二进制看看:

  0.1=>0.0001100110011001…(无限循环)

  0.2=>0.0011001100110011…(无限循环)

  双精度浮点数的小数部分最多支持52位,所以两者相加之后得到这么一串0.0100110011001100110011001100110011001100110011001100因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了0.30000000000000004。

  如何解决呢?

  首先将数乘以10的幂次方去掉小数位得到可以转化二进制的整数,计算之后再还原。

  /**

  **除法函数,用来得到精确的除法结果

  **说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。

  **调用:accDiv(arg1,arg2)

  **返回值:arg1除以arg2的精确结果

  **/

  functionaccDiv(arg1,arg2){

  vart1=0,t2=0,r1,r2;

  try{

  t1=arg1.toString().split(".")[1].length;

  }

  catch(e){

  }

  try{

  t2=arg2.toString().split(".")[1].length;

  }

  catch(e){

  }

  with(Math){

  r1=Number(arg1.toString().replace(".",""));

  r2=Number(arg2.toString().replace(".",""));

  return(r1/r2)*Math.pow(10,t2-t1);

  }

  }

  /**

  **加法函数,用来得到精确的加法结果

  **说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。

  **调用:accAdd(arg1,arg2)

  **返回值:arg1加上arg2的精确结果

  **/

  functionaccAdd(arg1,arg2){

  varr1,r2,m,c;

  try{

  r1=arg1.toString().split(".")[1].length;

  }

  catch(e){

  r1=0;

  }

  try{

  r2=arg2.toString().split(".")[1].length;

  }

  catch(e){

  r2=0;

  }

  c=Math.abs(r1-r2);

  m=Math.pow(10,Math.max(r1,r2));

  if(c>0){

  varcm=Math.pow(10,c);

  if(r1>r2){

  arg1=Number(arg1.toString().replace(".",""));

  arg2=Number(arg2.toString().replace(".",""))*cm;

  }else{

  arg1=Number(arg1.toString().replace(".",""))*cm;

  arg2=Number(arg2.toString().replace(".",""));

  }

  }else{

  arg1=Number(arg1.toString().replace(".",""));

  arg2=Number(arg2.toString().replace(".",""));

  }

  return(arg1+arg2)/m;

  }

  /**

  **乘法函数,用来得到精确的乘法结果

  **说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。

  **调用:accMul(arg1,arg2)

  **返回值:arg1乘以arg2的精确结果

  **/

  functionaccMul(arg1,arg2){

  varm=0,s1=arg1.toString(),s2=arg2.toString();

  try{

  m+=s1.split(".")[1].length;

  }

  catch(e){

  }

  try{

  m+=s2.split(".")[1].length;

  }

  catch(e){

  }

  returnNumber(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);

  }

  二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现。

赞(9)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程