谁都知道 javascript 语言本身精度限制, 楼主遇到的问题很多人都遇到过。 看楼主发了好几个帖子了, 就提醒一下。如果对 javascript 语言本身的设计有兴趣可以参考一下设计文档。如果不能四舍五入, 建议换成其它精度更高的语言以满足你的需要.

解决方案 »

  1.   

    //谁都知道 javascript 语言本身精度限制
    //如果不能四舍五入, 建议换成其它精度更高的语言以满足你的需要.
    这种说法是错误的!都已经精确到小数点16位了,还满足不了需要?你说,又有哪种语言比这更精确的?C?、VB?小数存在精确问题,不是具体某种语言造成的,而是二进制本身的局限所致
    你将十进制的0.3手工转换为二进制(方法就是乘2取整)你就知道了,无穷无尽的尾数!
    所以说只要你采用了浮点运算,不管你是用javascript 还是VBS 还是 C,你都不得不面对精度的问题,只不过其它语言将这个问题在一些傻瓜面前隐藏住了,而 js 没有罢了。
    当然,这并不是说,0.3这个数字不能在计算机中精确保存,你完全可以可以用整数“3”加“小数位数”这种方法保存它。但你若用小数的形式来保存它,就不得不面对精度的问题。
    说这么多的废话还不如说一句解决楼主问题的实话:var a=1.66+1.77
    var a=Math.round(a*1000)/1000 //这个数字根据需要保留的位数而定
      

  2.   

    /////////////////////////////////
    1.66+1.77=3.4299999999999997
    1.09+1.98=3.0700000000000003 
    我都不知道是什么规律???
    下面代码大家都可以试试一下,我要求准确的计算,不能四舍五入
    ///////////////////////////////////
    你采用了小数运算,而你又要显示象十进制运算那样自然的结果的话,你就不能不四舍五入!
    你只需将四舍五入的位数设大一点就可以解决问题了:var a=Math.round(a*1000000000000)/1000000000000这样得到的结果完全是你运算所需要得到的结果,除非你的运算结果的确是一个超过15位的小数或无穷小数(搞什么科研?需要这么高的精度?),那么看来javascript就无能为力了。
      

  3.   


    顺便说一下,VB 的精度是双精度能表示小数点后14位的小数当然它能表示的数值是10的-324次方到10的+308次方之间,但无论多大的数值,其不为“零”的有效位最多是15位,
    相比这下,JS 精明多了,可以是17位。至于C,好象也是17位,其它语言不怎么了解,但相信也不会多到那里去。
      

  4.   

    To: qiqunet(瑞旗·广东) 
    我回复的时候没有仔细考虑,多谢指点。
    在 Java 中,楼主的这个运算同样是这个值:
    1.66+1.77=3.4299999999999997
    1.09+1.98=3.0700000000000003 查了一下 Java 浮点类型的一些说明:所有浮点计算都遵从 IEEE 754 规范。
    注:浮点类型的数据不适合在不容许舍入误差的计算领域使用。比如,命令System.out.println(2.0-1.1)将会打印0.8999999999999999,而不是你所希望的 0.9 。这种舍入的错误产生的原因是因为浮点数实际上是用二进制系统表示的。而分数 1/10 在二进制系统中没有精确的表示,其道理就如同在十进制系统中无法精确表示 1/3 一样。如果你需要进行不产生舍入误差的精确数字计算,你需要使用 BigDecimal 类。其它我就不多说了,参考链接:
    IEEE-754 References
    http://www.etsimo.uniovi.es/~antonio/uned/ieee754/IEEE-754references.html
    ----------------
    ... JavaScript uses IEEE-754 double precision floating-point with round-to-nearest value mode to perform all of its arithmetic operations including its input string to numeric conversion routine. ...
    ----------------
      

  5.   

    我引用 Java 部分的说明在《第 6 版Java 2 核心技术 卷I:基础知识》 36页
      

  6.   

    只不过其它语言将这个问题在一些傻瓜面前隐藏住了
    ----------------
    qiqunet(瑞旗·广东) 是在骂我(我们就事论事)?
      

  7.   

    还没有揭帖呀。我提供一个解决办法如下
    <script language=javascript>
     function jjcc(v1,v2,n,typ){
    /*
      v1 v2 是两个操作数
      n  是最大小数位数   一定要大于等于两个操作数的小数位数 否则会出异常
      也可以在这里把最大小数位数改为自动判断  
      type 是类型  'add' 加  'min' 减 'mul' 乘  
    */
     var s1=Number(v1.toFixed(n).replace(".",""));
     var s2=Number(v2.toFixed(n).replace(".",""));
     if(typ=='add'){
       var ret=String(s1+s2);
       return Number(ret.substring(0,ret.length-n)+"."+ret.substring(ret.length-n));
     }else if(typ=='min'){
       var ret=String(s1-s2);
       return Number(ret.substring(0,ret.length-n)+"."+ret.substring(ret.length-n));
     }else if(typ=='mul'){
       var ret=String(s1*s2);
       return Number(ret.substring(0,ret.length-2*n)+"."+ret.substring(ret.length-2*n));
     }
     }
     alert(jjcc(1.66,1.77,2,"add")+" "+(1.66+1.77)+"\n"
               +jjcc(1.66,1.77,2,"min")+" "+(1.66-1.77)+"\n"
       +jjcc(1.66,1.77,2,"mul")+" "+(1.66*1.77));
     alert(jjcc(1.6,1.77,2,"add")+" "+(1.6+1.77)+"\n"
               +jjcc(1.6,1.77,2,"min")+" "+(1.6-1.77)+"\n"
       +jjcc(1.6,1.77,2,"mul")+" "+(1.6*1.77));
     alert(jjcc(3,1.77,2,"add")+" "+(3+1.77)+"\n"
               +jjcc(3,1.77,2,"min")+" "+(3-1.77)+"\n"
       +jjcc(3,1.77,2,"mul")+" "+(3*1.77));
    </script>