程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

浮点数的运算精度丢失

发布于2019-10-28 17:29     阅读(2328)     评论(0)     点赞(25)     收藏(0)


引出

打开Python编译器,输入 0.1+0.2, 期待的结果是0.3,但是输出为:

0.30000000000000004

有点小尴尬,这是为什么呢?

解惑

其实这设计到了计算机的浮点数存储是以二进制进行存储的。

说二进制不太形象,换成我们最长使用的十进制和分数

1/5,使用小数表示为0.2,但是1/3,使用小数表示就是一个无限循环小数:0.3333333, 也就是说,分数的 1/3+1/3=2/3,但如果使用小数:0.3333+0.3333=0.6666, 结果只会无限接近2/3,而不会等于2/3

因为把10分成三份,是不能够整分的。同样,把2分成十份,也不能整分。考虑到2整分只能分成两份,也就是说,二进制只能精确表示十进制小数0.5

十进制到二进制的转换在此略过。

十进制的0.1,转换成二进制是:0.00011001100110011无限循环的小数,所以二进制的小数运算,就会出现上面的1/3+1/3的情况,无法精确计算,只能够近似表示。那为什么python这些语言,我们在使用的时候没有察觉到这个问题呢?因为编译器自觉的帮我们做了近似的处理。

和十进制无法精确表示分数的1/3同样,二进制也无法精确表示十进制的小数。

分析

为了方便分析,我们讲计算机存储的字节数量进行缩减,我们假设小数点后只能保存8为小数。

十进制的0.1,转换成二进制为:0.00011001 (再反转回十进制,就会发现精度的丢失了,十进制是:0.09765625)

十进制的0.2,转换成二进制为:0.00110011 (反转回十进制,为:0.19921875)

加法运算:

十进制

0.1+0.2=0.3

二进制

0.00011001+0.00110011=0.01001100 (转成十进制:0.296875)


当然,计算机中存储的位数要比8位多,python浮点数占用8个字节,64位。但因为是无限小数,并不是位数多了就会准确。

那么如何做这种精度的计算呢?其实很简单,精度丢失是小数才会有,只要转成整数,就不会有这个问题了。比如Python中:

(1.0+2.0)/10

结果:0.3, 没毛病。

当然,这个0.3也不是精确的0.3,但会在显示过程进行精度转换,通过整数运算,避免了小数运算过程中的丢失精度问题。



所属网站分类: 技术文章 > 博客

作者:精灵

链接:https://www.pythonheidong.com/blog/article/147372/9498657e29259921ad71/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

25 0
收藏该文
已收藏

评论内容:(最多支持255个字符)