按 ‘ 实数 ’ 标签归档

程序员入伙书——两个世界

作为程序员,我们常往来于两个世界之间:计算机世界和现实世界。为了快速地让你感受到这两个世界的不同,我举一个例子。请在Python(啥?)的“>>> ”提示符后输入这样一行:

int(0.7 / 0.1)

现在先不要按Enter(回车)键,停下来,听我解释一下:这句话意思是,计算0.7除以0.1所得的商,取其整数部分。这个简单的除法,你觉得结果会是什么?

7,对吧?现在,敲回车,看看计算机认为结果是什么。

>>> int(0.7 / 0.1)
6
>>>

😮 😮 😮

为了弄清楚这个6是怎么出来的,我们先把“取整数部分”去掉,只留下0.7 / 0.1——如果你曾经听说过“调试”这个词,我们现在就是在调试:

>>> 0.7 / 0.1
6.999999999999999
>>>

现在我们至少可以理解,为什么“取整数部分”之后的结果等于6了,因为6.999999999999999的整数部分确实等于6(虽然四舍五入等于7,但“取整数部分”的操作是比较憨傻的)。可是可是,为什么0.7 / 0.1不正好等于7呢?这就是计算机世界和现实世界的差别之一。完美的数学世界里,任意两个实数之间必然存在无穷个实数,而计算机不这么认为。因为计算机的位数有限,它能表达的实数是有限的,实数之间总是存在一个个“空隙”,在计算机的世界里,“两个相邻的实数”是合理的说法。不精确但是意思到了的类比是,在只能显示五个数字的计算器液晶屏上,刚刚比1.0000大的下一个数就是1.0001,而介于其间的其他数,如1.00005、1.0000342376,则无法被这个液晶屏精确表达。

说出来你可能不信,0.1就是一个计算机无法精确表达的数字。这个数字对于我们这些习惯了十进制的人来说,是如此的简洁。可是机器用二进制思考,在二进制的世界里,十进制的0.1是一个无限循环小数:0.000101000101…,无法被精确表示。

再考虑这段例子:

>>> 1e10
10000000000.0
>>> 1e10000
inf
>>> 

1e10的意思是1乘以10的10次方,计算机心领神会地把这个数字表达出来了。1e10000的意思是1乘以10的10000次方,计算机口吐白沫地说:这个数……太大了……这就是传说中的“无穷大”吧?
猛击阅读全文