大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子

  1. alert(45.6*13);

结果居然是592.800000000001,当然加法之类的也会有这个问题

那这是js的错误吗?

当然不是,你的电脑做着正确的二进制浮点运算,但问题是你输入的是十进制的数,电脑以二进制运算,这两者并不是总是转化那么好的,有时候会得到正确的结果,但有时候就不那么幸运了

  1. alert(0.7+0.1);//输出0.7999999999999999
  2. alert(0.6+0.2);//输出0.8
  3.  

你输入两个十进制数,转化为二进制运算过后再转化回来,在转化过程中自然会有损失了

但一般的损失往往在乘除运算中比较多,而JS在简单的加减法里也会出现这类问题,你也看到了,这个误差也是非常小的,但是却是不该出现的

那该怎么解决呢,ECMA4似乎给了解决方法,但是现在倒不是那么实用的

一种方法,比如0.7+0.1,先把0.1和0.7都乘10,加完之后再除10

另外可以自己写点函数来解决这个问题,自己百度谷歌一下应该有很多,但是最好还是不要用JS做一些复杂的浮点运算,毕竟JS更多的作用不在于此

  1. <script type="text/javascript">
  2.  
  3. // 两个浮点数求和
  4. function accAdd(num1,num2){
  5. var r1,r2,m;
  6. try{
  7. r1 = num1.toString().split('.')[1].length;
  8. }catch(e){
  9. r1 = 0;
  10. }
  11. try{
  12. r2=num2.toString().split(".")[1].length;
  13. }catch(e){
  14. r2=0;
  15. }
  16. m=Math.pow(10,Math.max(r1,r2));
  17. // return (num1*m+num2*m)/m;
  18. return Math.round(num1*m+num2*m)/m;
  19. }
  20.  
  21. // 两个浮点数相减
  22. function accSub(num1,num2){
  23. var r1,r2,m;
  24. try{
  25. r1 = num1.toString().split('.')[1].length;
  26. }catch(e){
  27. r1 = 0;
  28. }
  29. try{
  30. r2=num2.toString().split(".")[1].length;
  31. }catch(e){
  32. r2=0;
  33. }
  34. m=Math.pow(10,Math.max(r1,r2));
  35. n=(r1>=r2)?r1:r2;
  36. return (Math.round(num1*m-num2*m)/m).toFixed(n);
  37. }
  38. // 两数相除
  39. function accDiv(num1,num2){
  40. var t1,t2,r1,r2;
  41. try{
  42. t1 = num1.toString().split('.')[1].length;
  43. }catch(e){
  44. t1 = 0;
  45. }
  46. try{
  47. t2=num2.toString().split(".")[1].length;
  48. }catch(e){
  49. t2=0;
  50. }
  51. r1=Number(num1.toString().replace(".",""));
  52. r2=Number(num2.toString().replace(".",""));
  53. return (r1/r2)*Math.pow(10,t2-t1);
  54. }
  55.  
  56. function accMul(num1,num2){
  57. var m=0,s1=num1.toString(),s2=num2.toString();
  58. try{m+=s1.split(".")[1].length}catch(e){};
  59. try{m+=s2.split(".")[1].length}catch(e){};
  60. return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);
  61. }
  62.  
  63. </script>
  64.  
  65. <script>
  66. document.write("使用js原生态方法");
  67. document.write("<br/> 1.01 + 1.02 ="+(1.01 + 1.02));
  68. document.write("<br/> 1.01 - 1.02 ="+(1.01 - 1.02));
  69. document.write("<br/> 0.000001 / 0.0001 ="+(0.000001 / 0.0001));
  70. document.write("<br/> 0.012345 * 0.000001 ="+(0.012345 * 0.000001));
  71. document.write("<br/><hr/>");
  72. document.write("<br/>使用自定义方法");
  73. document.write("<br/> 1.01 + 1.02 ="+accAdd(1.01,1.02));
  74. document.write("<br/> 1.01 - 1.02 ="+accSub(1.01,1.02));
  75. document.write("<br/> 0.000001 / 0.0001 ="+accDiv(0.000001,0.0001));
  76. document.write("<br/> 0.012345 * 0.000001 ="+accMul(0.012345,0.000001));
  77. </script>

js浮点数精度问题的更多相关文章

  1. js浮点数精度丢失问题及如何解决js中浮点数计算不精准

    js中进行数字计算时候,会出现精度误差的问题.先来看一个实例: console.log(0.1+0.2===0.3);//false console.log(0.1+0.1===0.2);//true ...

  2. js精确计算(js浮点数精度问题)

    转自:http://talentluke.iteye.com/blog/1767138 大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子 alert(45.6*13 ...

  3. JS浮点数精度运算

    一般来讲,我们在项目中必不可少的需要进行各种数值的计算,但是这种计算全部放在服务端会给服务器带来很大的压力,所以势必要客户端来 分担一些计算的压力. 从客户端来说,JavaScript是一门弱类型语言 ...

  4. 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS浮点数计算精度问题

    本文讲解的是怎么实现一个工具库并打包发布到npm给大家使用.本文实现的工具是一个分数计算器,大家考虑如下情况: \[ \sqrt{(((\frac{1}{3}+3.5)*\frac{2}{9}-\fr ...

  5. 关于js浮点数计算精度不准确问题的解决办法

    今天在计算商品价格的时候再次遇到js浮点数计算出现误差的问题,以前就一直碰到这个问题,都是简单的使用tofixed方法进行处理一下,这对于一个程序员来说是及其不严谨的.因此在网上收集了一些处理浮点数精 ...

  6. js浮点数计算问题 + 金额大写转换

    一 js浮点数计算问题解决方案: 1.使用 NumberObject.toFixed(num) 方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 2.较精度计算浮点数 ...

  7. js中精度问题以及解决方案

    js中的数字按照IEEE 754的标准,使用64位双精度浮点型来表示.其中符号位S,指数位E,尾数位M分别占了1,11,52位,并且在ES5规范中指出了指数位E的取值范围是[-1074, 971]. ...

  8. js浮点数乘除法

    JS在处理浮点数计算时经常会遇到精度的问题,上一篇博客封装了JS浮点数加减法的方法,这一次来封装一下js浮点数乘除法运算. 其实浮点除法的封装跟加减法的封装原理是一样,只是在第一次计算完后会再复位小数 ...

  9. WebGL着色器32位浮点数精度损失问题

    问题 WebGL浮点数精度最大的问题是就是因为js是64位精度的,js往着色器里面穿的时候只能是32位浮点数,有效数是8位,精度丢失比较严重. 这篇文章里讲了一些处理方式,但是视坐标这种方式放在我们的 ...

随机推荐

  1. js数组和对象互转方法

    <script> let arr = [2, 3, 4, 2, 3, 4]; // 数组转化为对象 function toObject(arr) { let obj = { } for(l ...

  2. html系列教程--文本格式化

    <b>定义粗体文本</b> <br /> <strong>定义加重语气</strong> <br /> <big>定 ...

  3. C# List<T>中Select List Distinct()去重复

    List<ModelJD> data = myDalJD.GetAllDataList(); List<string> list= new List<string> ...

  4. 关于ql createNativeQuery生成json数据

    当用createNativeQuery执行原生sql语句时,返回的数据json格式是只有值,没有键名的,在这种情况下要用Map.class对sql语句中的字段进行Map映射,这样返回的数据的json格 ...

  5. floyd学习中

    #include<iostream> #include<math.h> #include<stdio.h> using namespace std; //long ...

  6. EC读书笔记系列之10:条款16、17

    条款18 让接口容易被正确使用,不易被误用 记住: ★“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容 ★“阻止误用”的办法包括建立新类型.限制类型上的操作,束缚对象值,以及消除客户的 ...

  7. leetcode Jump Game II python

    @link http://www.cnblogs.com/zuoyuan/p/3781953.htmlGiven an array of non-negative integers, you are ...

  8. mysql 存储过程中的declare 和 set @的两种变量的区别

    两者在手册中的说明: DECLARE var_name[,...] type [DEFAULT value]这个语句被用来声明局部变量.要给变量提供一个默认值,请包含一个DEFAULT子句.值可以被指 ...

  9. jQuery中的.live()与die()

    翻译原文地址:http://www.alfajango.com/blog/exploring-jquery-live-and-die/ 很多开发者都知道jQuery的.live()方法,他们大部分知道 ...

  10. windows中copy命令详解

    功能:将一份文件或者多份文件复制到另一个位置 用法: copy [/D] [/V] [/N] [/Y|/-Y] [/Z] [/A | /B] source [/A | /B] [+ source [/ ...