一个关于JS的运算问题

小虫虫 发布于 2013/08/27 16:50
阅读 306
收藏 2

js里面一个问题,底下这段脚本弹出的为什么是0.30000000000000004?求解。。。。

<script type="text/javascript">
    var sum1 = 0.1;
    var sum2 = 0.2;
    alert(sum1 + sum2);
</script>

 

以下是问题补充:

@小虫虫:看了网上给出的回答,都各不相同,而且大都是专业名词串串。。。 (2013/08/27 17:01)
加载中
0
子木007
子木007

以前收藏的一段文字,供楼主参考(好像是来自 iteye)

---------------------------------------------

为什么会产生这种精度丢失的问题呢?是javascript语言的bug吗? 
我们回忆一下大学时学过的计算机原理,计算机执行的是二进制算术,当十进制数不能准确转换为二进制数时,这种精度误差就在所难免。 
再查查javascript的相关资料,我们知道javascript中的数字都是用浮点数表示的,并规定使用IEEE 754 标准的双精度浮点数表示: 
IEEE 754 规定了两种基本浮点格式:单精度和双精度。 
  IEEE单精度格式具有24 位有效数字精度(包含符号号),并总共占用32 位。 
  IEEE双精度格式具有53 位有效数字精度(包含符号号),并总共占用64 位。 
这种结构是一种科学表示法,用符号(正或负)、指数和尾数来表示,底数被确定为2,也就是说是把一个浮点数表示为尾数乘以2的指数次方再加上符号。下面来看一下具体的规格: 

        符号位         指数位         小数部分 指数偏移量
单精度浮点数 1位(31) 8位(30-23) 23位(22-00) 127
双精度浮点数 1位(63) 11位(62-52) 52位(51-00) 1023

我们以单精度浮点数来说明: 
指数是8位,可表达的范围是0到255 
而对应的实际的指数是-127到+128 
这里特殊说明,-127和+128这两个数据在IEEE当中是保留的用作多种用途的 
-127表示的数字是0 
128和其他位数组合表示多种意义,最典型的就是NAN状态。 
知道了这些,我们来模拟计算机的进制转换的计算,就找一个简单的0.1+0.2来推演吧(引用自http://blog.csdn.net/xujiaxuliang/archive/2010/10/13/5939573.aspx): 
Java代码   收藏代码
  1. 十进制0.1    
  2.  => 二进制0.00011001100110011…(循环0011)     
  3.  =>尾数为1.10011001100110011001100(共52位,除了小数点左边的1),指数为-4(二进制移码为00000000010),符号位为0    
  4.  => 计算机存储为:0 00000000100 1001100110011001111001    
  5.  => 因为尾数最多52位,所以实际存储的值为0.00011001100110011001100110011001100110011001100110011001    
  6.  而十进制0.2    
  7.  => 二进制0.0011001100110011…(循环0011)    
  8.  =>尾数为1.10011001100110011001100(共52位,除了小数点左边的1),指数为-3(二进制移码为00000000011),符号位为0    
  9.  => 存储为:0 00000000011 1001100110011001111001    
  10.  因为尾数最多52位,所以实际存储的值为0.00110011001100110011001100110011001100110011001100110011    
  11.  那么两者相加得:        
  12.  0.00011001100110011001100110011001100110011001100110011001    
  13. +  0.00110011001100110011001100110011001100110011001100110011  
  14.  =  0.01001100110011001100110011001100110011001100110011001100    
  15.  转换成10进制之后得到:0.30000000000000004  

从上述的推演过程我们知道,这种误差是难免的,c#的decimal和Java的BigDecimal之所以没有出现精度差异,只是因为在其内部作了相应处理,把这种精度差异给屏蔽掉了,而javascript是一种弱类型的脚本语言,本身并没有对计算精度做相应的处理,这就需要我们另外想办法处理了。 
小虫虫
小虫虫
谢谢,受教了。。。
苏生不惑
苏生不惑
科普啊
0
小耶果
小耶果
无理数能定义整个宇宙,区区人类的计算机就想精确描述.愚蠢的人类.
小虫虫
小虫虫
有理数。。。
0
sjunjun
sjunjun
js的bug,toFixed一下就好了
返回顶部
顶部