竹笋

首页 » 问答 » 常识 » 为什么将01累加100次,得不到10
TUhjnbcbe - 2025/7/21 17:44:00

将0.1累加次也得不到10

前言

看了题目,相信不少小伙伴已经知道本文想要介绍的内容了吧?这应该算是我们代码之路上很早就会发现的现象:浮点型数据相加并不会等于一个整数,比如题目所说,个0.1不等于10。当然这是有前提的:

之前面对这种情况,基本都是把小数扩大到整数倍之后再做对应的除法操作,将其还原。不过说来惭愧,一直都没有去思考,为什么浮点数计算会出现这种情况。恰巧在看《程序是怎样跑起来的》时候,看到了这方面的解释,所以特地落笔写下这篇文章。

《程序是怎样跑起来的》的pdf可以在后台回复:我要书。即可得到它(以及其他相关编程电子书)。

正文

二进制的小瑕疵

小A同学:老M,我最近遇到一个现象,为啥float相加不是我想要的整数结果呢?比如10个0.1,竟然不是1。计算机脑子就这么不好使么?

MDove同学:不好使?这你就是错怪计算机了。不是脑子不好使,而是压根就是“智障”。它永远不会算这类运算。

小A同学:啊?这不就是Bug了么?

MDove同学:还真不是Bug,咱们慢慢道来…探究这个问题之前,我们回忆一个小常识:我们都知道计算机使用二进制来表示我们所有的信息,那么小数也同样如此。

小A同学:咋滴?你脑子也不好使了?这不是废话么。

MDove同学:我最开始也没有感觉这里有什么不对。直到从书中看到一句话:有一些十进制数的小数无法转换成二进制数。

小A同学:无法转成二进制?

MDove同学:没错,这很好理解。就比如有些小数十进制也没办法表示。像三分之一,我们的十进制就无法表示。

小A同学:!!!难道说计算机遇到这种情况是取了近似值么?

MDove同学:没错,正是如此,是不是恍然大悟?这了解这个未免有些不够刨根问底。咱们继续聊…

二进制如何表示小数

MDove同学:二进制转十进制,十进制转二进制你应该会算吧?

小A同学:会啊,不就是按每一个的数值乘权值的位数减一次幂么。比如下图就是一个标准的用公式将二进制转为十进制:

MDove同学:没错就是这样,那二进制表示小数又什么不同呢?其实没有不同,一模一样,哈哈。下面用一个文中的例子,把.这个有小数点的二进制数转换成十进制数:

MDove同学:同样也是加权就和。

小A同学:这好像没啥问题呀?

二进制没办法精确的表示所有小数

MDove同学:当然没问题了!现在是二进制转十进制当然不会有问题…有问题的是十进制转二进制:有些十进制,二进制没办法表示。所以接下来让我们看一下会出现问题的地方。

MDove同学:小数点后4位用二进制数表示时对应的是:0.~0.(0.、0.、0.、0.0、0.、0.….不罗列了,一共能表示这么多)。我们来简单算一下他们分别能够表示的十进制:

MDove同学:到这问题就显而易见了:0.和0.是四位能表示最小的俩个准确二进制小数了。我们可以发现十进制的0.-0.二进制已经没办法表示了。

MDove同学:,我们可以看到对应十进制的一栏,0的下一位是0.。因此,这中间的小数,就无法用小数点后4位数的二进制数来表示。因为无法正确表示的数值,最后都变成了近似值。计算机这个功能有限的机器设备,是无法处理无限循环的小数的。

小A同学:那么这种特别的小数,二进制是怎么表示的呢?

MDove同学:这问题还真不好简单的说清楚。如果有兴趣的小伙伴,可以自行去《程序是怎样跑起来的》这本书中的3.4节一探究竟。

尾声

今天文章的内容,到此就结束了。其实这篇文章上上周就已经开始写,这周按道理讲应该是RxJava的内容。不过上周牵扯精力的事情比较的多,所有就很尴尬的延期到了这周发布。关于RxJava可能、大概、也许要放一放,最近在用Kotlin写新项目,所以文章,准备聊一聊Kotlin中有趣的地方~

1
查看完整版本: 为什么将01累加100次,得不到10