0.2乘0.3为什么等于0.06(0.2为什么等于0.3000000...4)

作者| 慕课网精英讲师 咚咚呛

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!

最近有同学在问答区提到了一个很有意思的问题:为什么0.1 0.2 = 0.30000...4?

这个问题是怎么来的呢?有Python环境的同学,只要打开Python终端,输入0.1 0.2,就能得到0.3000000..4的结果。

0.2乘0.3为什么等于0.06(0.2为什么等于0.3000000...4)(1)

那到底这是为什么?今天就来探讨一下这个问题。

二进制

首先我们知道,计算机是以二进制的方式存储数据的。

比如:5=101(2),15=1111(2),25=11001(2),把十进制转换成二进制的方式叫做重复相除法,过程大致是这样子的。

25/2= 12.....1 12/2=6......0 6/2=3......0 3/2=1......1 1/2=0......1 # 遵循两个原则 # 1. 重复相除,直到商为0结束 # 2. 余数结果从下往上得到二进制形式

我们也可以按照按权展开法,得到二进制转换成十进制的结果,过程大致是这样子的。

11001= 1*2^4 1*2^3 1*2^0= 16 8 1= 25。

不过以上只是整数形式的转换方法,小数在计算机硬件上也是使用二进制表示的,不过转换的方法有些不一样,十进制小数转换成二进制的方法叫做重复相乘法

重复相乘法

一般来说如果一个小数既有整数部分又有小数部分,那么这个小数转换成二进制是分成两个部分转换的,整数部分使用重复相除法,小数部分使用重复相乘法

重复相乘法的大概过程是这个样子的,比如想把十进制小数0.125转换成二进制。

0.125*2=0.25=0.25 0 0.25*2=0.5=0.5 0 0.5*2=1=0.0 1 # 注意,这里把结果分成了小于1和大于等于1的两个部分,当小于1的部分=0时,结束运算。 # 大于等于1的部分,从上往下得到001即为0.125的小数结果(0.001)。

再举一个复杂一点的例子:

0.2乘0.3为什么等于0.06(0.2为什么等于0.3000000...4)(2)

精度问题

小学我们学过,小数分为有限小数无限小数,无限小数又分为无限循环小数无限不循环小数

同样的,对于二进制小数来说,同样有有限小数和无限小数两大类。那么重点来了,0.1和0.2在十进制小数里面是有限小数,但是使用二进制表示的时候就不是了。

不信你使用重复相乘法计算一下试试:

# 运算可以得到: 0.1=0.0001100110011... # 它实际上是一个无限循环小数 0.1=0.0(0011) # 括号的0011即是无限循环的部分 # 同理得到0.2的二进制 0.2=0.(0011) # 括号的0011即是无限循环的部分

所以计算机是无法准确表示0.1和0.2两个数的,只能无限逼近这两个数。假设计算机使用10位精度,则计算机里面,0.1和0.2是这样子的。

0.1=0.0001100110(2) 0.2=0.0011001100(2) # 现在我们使用二进制加法,运算两个二进制数 0.0001100110 0.0011001100 ———————— 0.0100110010(2)

再把这个结果转换成十进制

0.0100110010(2) = 1*(1/4) 1*(1/32) 1*(1/64) 1*(1/512) = 0.298828125< 3

可以看到这个数值已经很接近3了,如果把精度再调高为16位、32位甚至是64位,会得到更加接近3的结果。这就解释了为什么在十进制中运算和在二进制中运算,会得到不一样的结果。

但是,这就完了吗?还没有。其实可以归纳总结到,不管精度是多少,这个结果应该是恒小于3的,而不可能是大于3的结果,因为在截取有效数时,总是把末尾的数值去掉了,那为什么在Python这里会大于3呢?

这主要是因为除了精度以外,计算机浮点数表示数据的时候还有对阶零舍一入等等的操作,会使得实际操作数比原操作数大一些。

在十进制中有四舍五入法。比如:

0.499999约等于 0.5 0.41999约等于 0.4

同样的,在二进制中,有零舍一入的操作。

0.1001(2) 约等于 0.10(2) 0.1011(2) 约等于 0.11(2)

所以在二进制运算中,为了进行有效数值的运算,会对浮点数尾数进行零舍一入的操作,从而导致真实值和计算值的偏差。

这就可以合理的解释在Python中0.1 0.2为什么等于0.3000...4了。

谢谢大家,希望对同学们有所帮助。

欢迎关注「慕课网」,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页