彻底搞懂为什么计算机表达的浮点数(小数)不准确?

        无论任何编程语言,在表达数值的时候,都具备表达整数和小数的能力。

        但是在表达小数的时候,往往不能准确的表达。举个例子,0.3这个小数,计算机就无法准确的表达。

        为什么呢?

        这与计算机通过硬件对数据存储的机制有关。

一、计算机如何存储和表达整数

        人们都说,计算机实际上很傻,他连2都不认识。只知道0和1.

        存储元件,通电即为1,不通电即为0.

        那么一个存储元件能表达多少种状态呢?很显然就是0和1两种状态。

        如果两个存储元件排在一起,那能表达多少种状态呢?我们可以通过控制开关,实现00,01,10,11,四种状态。也就是2的2次方。

        当我们有三个存储元件排在一起,那就是000,001,010,011,100,101,110,111这样8种状态,也就是2的3次方。

        以此类推:

        N个存储元件排列在一起,就可以表达2的N次方个状态。

        如果对每一个状态从0开始编号。那么就可以说,表达了0到2的N次方-1个整数了。

        按照数学的方式来表达一个公式的话。那么任意的二进制数排列在一起,表达一个十进制整数的公示就变成:

        二进制各位从低到高(从右至左)依次乘以2的N次方,其中,N从0开始。

        例如:1100 = 0 * 2^0 + 0 * 2^1 + 1 * 2^2 + 1 * 2^{3} = 12

        这就是整数的表达方法。

        这里其实蕴含着背后的一个机理,那就是整数是离散的数,1,2,3,4,5。。。。。。,是固定的离散数,计算机都可以通过状态的排列叠加来准确的表达出来。

        当然,整数还分为有符号整数(也就是带正负号)和无符号整数两部分。具体的就不展开了。

二、计算机如何存储和表达小数

        那么问题来了。

        如何存储和表达小数呢?

        存储小数的话题比较复杂,如果想解开谜题可能要花些笔墨,大家自行查询吧。你会顺便了解浮点数(float)名字的由来。

        着重来了解一下,表达小数的问题。

        按照计算机硬件存储整数的套路,计算机用二进制表达小数换算为十进制小数的方式也是一样的。

        例如:

        11.101 = \left (1 * 2^{1} + 1 * 2^{0} \right )+ \left ( 1 * 2^{-1} + 0 * 2^{-2} + 1 * 2^{-3}\right ) = 3.625

        以小数点为分割,整数部分和小数部分分别计算。

三、为什么计算机表达小数不准确?

        了解了计算机表达整数和表达小数的方法。你一定注意到了一个细节。那就是,整数作为离散的数据,计算机可以完美的通过多个二进制数的状态叠加来覆盖所有的整数。

        然而,小数是连续的,或者数学上也称之为“无限”的。计算机可以通过状态的排列叠加表达超级超级多的状态,但是仍然是有限的。因为硬件是实实在在的就那么多。

        比如:0.3这个小数。如果通过二进制存储元件来组合表达,我们怎么来做呢?这里只能采用贪新算法。

        首先,我们在最高位赋值1,看看表达的小数是否超过0.3。

                0.1 = 1 * 2^{-1} = 0.5

        已经超过了0.3,遂赋值为0,次高位继续上述操作。

                0.01 = 0 * 2^{-1} + 1 * 2^{-2} = 0.25

        接下来,继续尝试接近0.3,在第三高位赋值为1.

                0.011 = 0 * 2^{-1} + 1 * 2^{-2} + 1 * 2^{-3} = 0.375

        超过0.3,赋值为0,继续尝试,直至

                0.01001= 0 * 2^{-1} + 1 * 2^{-2} + 0 * 2^{-3} + 0 * 2^{-4} + 1 * 2^{-5} = 0.28125

        如此往复,尝试下去,将始终无法达到0.3,只能无限接近。但由于元件个数限制(表达容量),甚至无法做到无限接近。

        这就是为什么小数无法被准确表达的缘故。

        学会了就点个赞吧。:)

 

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎风工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值