为什么计算机中0.1+0.2不等于0.3?

liftword21小时前技术文章4


1+2=3,这是我们小时候就学过的一位数加减法。这道题非常简单,难度仅次于1+1=2.

什么?你觉得2-1=1更简单?啊这。

显然,按照常理来讲,0.1+0.2当然等于0.3

对于刚上小学二年级的小王来说事情没有那么简单。计算机课上,他用python编写了一个计算器,计算0.1+0.2的时候,却得到了0.30000000000000004这个离谱的答案。



和小王一样,我们在小学二年级的高数课上就学过无穷小量的概念。这里0.3和0.30000000000000004只相差了一个很小的值,可以认为这是合理的误差。不过,如果遇到一些极端情况,这样的bug很有可能导致财务上的损失。举个例子,小王需要购买x只笔和y个本子送给二年级的同学们做高数题,他计算出需要支付的金额会超过实际需要的金额。若是他给全国乃至全世界的小学二年级的小朋友购买笔记本和笔,那么小王将额外产生一笔不必要的损失。



那么python中为什么0.1+0.2不会得到0.3,反而得到0.30000000000000004呢?这要从二进制讲起。

我们今天所用的计算机,即便是显示10101010这样的二进制数字,还是显示233的十进制数字,他们在内存里都用010101的二进制表示。比如,8这个数字就用1000表示。最高位的1表示1*2的3次幂,其他三位表示为0*2的2、1、0次幂。所有加起来,一共是8.

但这个世界上不是只有整数,无理数和小数也是宇宙的一部分。计算机又怎样表示小数呢?

这里以0.1为例。取小数部分0.1,乘2,若小于1则用0表示,否则1表示,同时去掉整数部分。

0.1到0.2,0.4,0.8三次变换得到的都是0,但下一次1.6,1.2,0.4得到110.类似的,这样得到了000110来表示0.1 。实际上,计算机中的位数远远超过我所举例部分。

同样,0.2也被表示为001100 … …



不同于整数,不是每一个小数的小数部分的处理都能完全精确。0.125这样的数字乘3次即可得到1,而0.124和0.126则相对于更容易丢失精度。因此,二进制表示的小数是不一定精确的,存在误差是很正常的。

幸运的是,python,C#等语言都有针对财务方面的精准的小数运算。使用python的decimal库,可以得到想要的精度。

也许有小学一年级的小朋友会问,为什么计算机不做成十进制,反而要做成二进制的呢?

您可以关注“Daniel谈技术”,我们后面会对计算机历史和芯片进行科普。

相关文章

Python 空值(None)详解

在Python中,空值是一个非常重要的概念,表示"没有值"或"空"的状态。让我们来详细了解一下。什么是空值?在Python中,空值用None表示。它是一个特殊的数据类型...

自学python第九天:布尔表达式和关键字in的示例代码

布尔表达式和关键字in的用法在Python中,“if”语句后面的条件表达式会被求值为布尔值(True或False)。当条件表达式的结果为True时,执行“if”块内的代码;否则跳过。代码:foods_...

每天学点Python知识:常量

在 Python 这门语言里,常量(constant)这个概念常常让初学者有些迷糊。毕竟,在很多其他语言中,我们可以用 const 或 final 来显式声明某个变量为常量,确保它的值不会被修改。而...

python中数值比较大小的8种经典比较方法,不允许你还不知道

在 Python 中比较数值大小是基础但重要的操作。以下是 8 种经典比较方法及其应用场景,从基础到进阶的完整指南:1. 基础比较运算符Python 提供 6 种基础比较运算符:a, b = 5, 3...

Python基础之变量、循环、函数(一)

本系列内容所用Python版本为anaconda,直接浏览器搜索下载安装即可!本次内容将为大家重点介绍Python的基础概念变量、循环、函数。一、变量变量是编程语言最重要的概念之一,变量标记或指向一个...