你以为你了解了浮点数?真相是很残酷!
小白:大神,咱们开始吧,我今天把数据类型和变量这章学完了呢。
大神:你先谈谈你对浮点数的理解吧。
小白: 浮点数就是带小数点的数呗,和整数相比特点就是计算不精确,但是不知道为什么不精确。
大神:好的,看来你似乎也没啥不理解的,来做个题,判断下0 == 0.0这个表达式是True还是False?
小白:False
大神:那你也False了,不过你现在不用知道原因,反正你知道原因也会忘记。现在就只需要知道,你知道了0 == 0.0是True的。
小白:。。。。。。好吧,默默的跑到编译器里面跑了一遍,还尝试了一下
1 == 0.9999999999999999999居然也是True。
大神:嗯,很多事情不用讲你也会发现的,所以不用上来就告诉你道理,等知道的事情多了,自然就懂道理了。来判断下(10/3-3-1/3)= 0是True还是False?
小白:这个是True,我还在编译环境里面运行了下,哈哈,这次没错了。
大神:嗯,等等,你编译环境是python 2.x,现在我们需要把它更换成3.x,你试着输入(10.0/3.0-3.0-1.0/3.0)看看结果。
小白:好吧,你就是不能让我对一次啊。。。结果是1.6653345369377348e-16这么奇怪啊,无语。
大神:好的,你现在就是体验到了浮点数计算是不精确的实际感受了。接着继续,1e5+1e-5>1e5 成立吗?
小白:True
大神:那么继续1e10+1e-10>1e10呢
小白:还是True
大神:你先计算下1e10 + 1e-1
小白:10000000000.1
大神:那你计算下1e10 + 1e-5
小白:10000000000.00001(这简直逗我数0嘛)
大神:那你在python里面运行下1e10+1e-6看看结果
小白:一脸懵逼了,python里面显示是10000000000.000002
大神:哈哈,你再试试1e10+1e-7,你就明白为什么1e10+1e-10>1e10是False了
小白:好吧,我猜到了这里面有坑,但是我不知道这个坑在小数点后几位
大神:总结下,这个其实是有效位数的问题,python里面15位有效数字准确性是能够保证的,16位就不准确了。
小白:已经懵了,那到底实际原因是啥呢?
大神:这里牵扯到浮点数二进制格式,作为课外作业吧,想搞清楚可以查IEEE 754 手动计算下。
大神:好了,这个其实并不重要,重要的是不要以为数学计算上是0,用浮点数计算也会是0。
编程和学数学不一样,数学需要每一步都正确才能开始下一步,编程因为实践性强,一些问题开始的时候不好解决,可以在后面学习过程中综合起来改。
好了,最后你再试一个7e10+1e-5,看看结果会如何?
小白:我勒个去,为什么python里面算出来会是70000000000.00002
大神:好啦,今天就教(虐)你到这把,IEEE作为课后思考题,你可以去算算。
发表评论