2.55乘100,结果竟不是255!.docVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
2.55乘100,结果竟不是255!.doc

2.55乘100,结果竟不是255!   很久以前,程序员成心文同学遇到了他编程史上的第一个浮点数误差Bug,这个Bug正如标题所述,在他的程序下2.55*100的结果竟是254.99999999999997,而非255。因为是初次遇到,所以他也不知道是怎么回事,但在请教中外俩.NET大牛无果后,他果断拍板决定“自己动手,丰衣足食”。   后来他终于找到了原因,简单地说:   计算机将小数部分0.55转换成二进制时会形成一个“0011”组合的无限循环,从而造成误差。解决办法是尽量用decimal类型替换double类型。   这位年轻的程序员将他的这次编程经历记录在了微博上,一不小心被小编扒了出来,于是IT之家就有了这篇关于“世界上只有10种人,一种懂二进制、另一种不懂”的文章(如图1)。   当然,除了上面的这位同学之外,小编还发现一位名叫周花卷的大牛也遇到了类似的问题,他在谷歌Chrome浏览器的开发者控制台(Win环境下F12/Mac环境按Command+Option+I可以打开一个“开发者工具”窗口,然后点上面的“Console”标签,你会看到一个控制台窗口)里输入“0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1”(一共10个0.1),按下回车后结果竟是0.99999999999999,这个问题同样也是二进制造成的(如图2)。   OK,下面进入正题,小编接下来要用更专业的解释来带大家飞,不懂二进制的也可以学习一下哈。      要搞清楚这个问题,我们先来理解一下进制的概念。在十进制中,一位数字我们可以使用0到9,比9多的时候就会变成10,这就是一个两位数了,也就是进位了,二进制也是一样,只不过一位数字只能使用0和1,再多就要进位了。那么进制的本质又是什么呢?我们随便拿一个十进制的数字来看一看(如图3):      看懂了没?一个十进制数实际上就是其中每一位数依次乘以10的0、1、2…次幂(权重),然后再把结果加起来,那么以此类推,二进制里面就是把上面的10换成2呗,我们来看一个(如图4):      于是二进制数1001也就是十进制数的9。到这里似乎还没什么问题,因为我们只讨论了整数呢,每一个十进制整数都可以转换成一个二进制整数,反过来,每一个二进制整数也都可以转换成一个十进制整数。不过,如果把小数也加进来呢?先看一个十进制的小数(如图5):      看懂了没?其实就是把10上面的指数变成了负数而已,不难吧。那么以此类推,二进制的小数也就是把10换成2呗,我们来看一个(如图6):   上面我们理解了进制的一些本质特性,算不过来也没关系,我们暂且先不管它,不过,这跟我们遇到的问题到底有什么关系?别急,我们再看一下当引入小数之后,进制之间的转换到底出了什么Bug。我们知道实数的数轴是连续的,每两个数字之间的部分是可以被无限分割的,举个例子,0和1之间的这部分,如果用十进制一位小数来分割的话,可以分成10份,也就是0.1、0.2、0.3……0.9、1,如果用二进制一位小数来分割的话,则只能分成两份,也就是0.1(十进制的0.5)、1。你发现了什么问题?无论小数点后面增加多少位数字,二进制永远只能以2来分割数轴,而十进制则是以10来分割数轴。   让我们回想一下小学的数学知识,在十进制中,如果要用有限小数来表示一个分数的值,那么这个分数的分母(化简之后)一定不能包含除了2和5以外的其他质因数,因为十进制以10来分割数轴,而10分解质因数的结果为2×5。举个例子:1/8、1/10、1/25都可以换算成有限小数(分别是0.125、0.1、0.04),因为这些分数的分母分解质因数之后只包含2或者5(8=2×2×2、10=2×5、25=5×5),而当分母包含其他质因数时,例如1/3、1/7、1/18这些则无法用有限小数来表示(也就是俗话说的“除不尽”)。如果我们把这个规律套用到二进制上会怎么样呢?2本身就是一个质数,无法分解质因数了,因此在二进制中,如果要用有限小数来表示一个分数的值,那么这个分数的分母一定只能包含2这一个质因数,换句话说,分母必须为2的幂(2、4、8、16、32……)。   好了,我们回头看看开头的题目,0.1换算成分数就是1/10,而1/10的分母是10,10并不是2的幂,因此,在二进制中并不能用有限小数来表示1/10这个值。事实上,如果将0.1转换成二进制,我们会得到一个无限循环小数:0.000110011001100……看到这里,很多人估计已经想明白了,没错,计算机的精度是有限的,并不能直接处理无限小数,对于无限小数必须要截短到某个位置把它变成有限小数,但截短之后这个数就不准了,必然就产生了一点误差,而连续加10次会将这种误差放大,当

文档评论(0)

yingzhiguo + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:5243141323000000

1亿VIP精品文档

相关文档