最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

聊聊Python中的浮點數(shù)運算不準(zhǔn)確問題

 更新時間:2021年03月16日 08:52:03   作者:一只闊愛的程序媛  
這篇文章主要介紹了聊聊Python中的浮點數(shù)運算不準(zhǔn)確問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

大家好,老 Amy 來了。之前就意識到一個問題,但是最近又有朋友提出來了,所以就想著干脆記錄下來,分享給大家叭~

啥問題呢?請看題:

也就是說,需要大家計算1.1-1的值,很多朋友會說:“emmm…這還不簡單,玩我呢?不就是0.1嘛”

但是如果你用 python 去執(zhí)行一下,會發(fā)現(xiàn)結(jié)果跟你想的不太一樣,如下圖:

這樣大家是不是發(fā)現(xiàn)了什么問題?是的,浮點數(shù)在運算過程中并沒有保證完全精確,是什么原因?qū)е铝诉@種現(xiàn)象呢?很多朋友就會竊喜:“這不就是 Python 的 bug 嘛~”

但實際上,這并不是 Python 中的 bug ,它和計算機硬件中如何處理浮點數(shù)有關(guān)。浮點數(shù)在計算機硬件中以二進(jìn)制的形式存在,但是我們現(xiàn)在看到的都是十進(jìn)制,而十進(jìn)制的浮點數(shù)不能都完全精確的表示為二進(jìn)制小數(shù)。

就比如說我們在十進(jìn)制數(shù)中無法用小數(shù)精確表示 1/3 一樣,在二進(jìn)制數(shù)中也無法用小數(shù)精確表示 1/10。顯然這樣子的說明并沒有十進(jìn)制中的 1/3 那么直觀,接下來我們嘗試去計算一下二進(jìn)制中的 1/10 :

十進(jìn)制的整數(shù)位是二進(jìn)制的整數(shù)位,十進(jìn)制的小數(shù)位是二進(jìn)制數(shù)的小數(shù)位。那現(xiàn)在我們拿到0.1

整數(shù)部分為0

小數(shù)部分為0.1,并順序取值

0.1*2=0.2<1取0
0.2*2=0.4<1取0
0.4*2=0.8<1取0
0.8*2=1.6>1取1
0.6*2=1.2>1取1
0.2*2=0.4<1取0
…

有沒有發(fā)現(xiàn)?在二進(jìn)制下,1/10 是一個無限循環(huán)小數(shù):0.00011001100110011…,顯然這樣的表示形式無法精確的表示浮點數(shù),最終的結(jié)果是近似 1/10 。在使用 IEEE-754 浮點運算標(biāo)準(zhǔn)的計算機硬件上,Python 的浮點數(shù)映射為 IEEE-754 雙精度浮點數(shù),共包含 53 位精度(這里指的是二進(jìn)制),在這個范圍下,這個最接近 1/10 的結(jié)果是:

3602879701896397/2∗∗55

這表示在計算機硬件中,1/10 的真實十進(jìn)制數(shù)值為:

0.1000000000000000055511151231257827021181583404541015625

那如何進(jìn)行精確的浮點數(shù)運算呢?有朋友提出四舍五入可以解決。那我們來仔細(xì)看一下四舍五入真的可以解決這個問題嗎?

四舍五入進(jìn)行解決

在 python 中,使用 round(number[, ndigits]) 來進(jìn)行四舍五入,其中 ndigits 表示保留幾位小數(shù),默認(rèn)為0。

我們來看代碼如下:

In [10]: round(0.6)
Out[10]: 1
In [11]: round(0.65,1)
Out[11]: 0.7
In [12]: round(0.64,1)
Out[12]: 0.6

上面代碼符合我們四舍五入的預(yù)期結(jié)果,但是不要著急,我們接著往下看:

In [13]: round(1.15,1)
Out[13]: 1.1
In [14]: round(0.5)
Out[14]: 0
In [15]: round(1.5)
Out[15]: 2

這樣看是不是有些問題,什么問題呢?按照四舍五入的話,round(1.15)會直接進(jìn)為1.2,但是此時并沒有,而是變?yōu)榱?.1。這是為什么呢?

如果沒有上面對浮點數(shù)的了解,僅從表象上很難去解釋。我們已經(jīng)知道了在計算機內(nèi)部,對于一些浮點數(shù)是無法精確表示的,比如上面代碼中 1.15,我們可以通過 format() 來看看它在計算機內(nèi)部更加具體的數(shù)值:

In [16]: format(1.15,".51f")
Out[16]: '1.149999999999999911182158029987476766109466552734375'

看到這個結(jié)果,我們就恍然大悟,為什么看到的結(jié)果會是1.1了。

但是接下來,可能會更加的困惑,因為對于 0.5 來說,是完全可以直接轉(zhuǎn)為二進(jìn)制表示的。但是round(0.5)結(jié)果卻為0?這是因為 round() 的工作原理為:對于 round(number[, ndigits]),如果 number 可以被正常處理,則它的值會被舍入到最接近的 10 的負(fù) ndigits 次冪的倍數(shù)上,對于與兩個倍數(shù)的差值(差值的絕對值)均相等的情況,則會選擇兩個倍數(shù)中的偶數(shù)。

# 最接近的10的負(fù)0次冪的倍數(shù)為0、1,并與0、1差值的絕對值相同,選擇偶數(shù)0
>>> round(0.5) 
0
# 最接近的10的負(fù)2次冪的倍數(shù)為0.12、0.13,并與0.12、0.13的差值的絕對值相同,選擇偶數(shù)0.12
>>> round(0.125, 2) 
0.12
# 最接近的10的負(fù)2次冪的倍數(shù)為0.13
>>> round(0.12548828125, 2) 
0.13

這個規(guī)則,用我們熟悉的話來說即為“ 四舍六入五成雙 ”。

使用decimal進(jìn)行浮點數(shù)的精確計算

那我們在 Python 中怎么進(jìn)行精確的浮點數(shù)計算呢,Python 標(biāo)準(zhǔn)庫為我們提供了decimal 這個模塊來解決這個問題,decimal 常用于需要精確處理浮點數(shù)的場合,比如銀行賬戶金額、貨幣加減等。

In [17]: from decimal import Decimal
In [18]: 0.1-0.09
Out[18]: 0.010000000000000009
In [19]: Decimal('0.1')-Decimal('0.09')
Out[19]: Decimal('0.01')

同樣,我們可以使用它來查看對于不能精確表示的浮點數(shù)在計算機內(nèi)部的具體數(shù)值:

In [20]: Decimal.from_float(1.1)
Out[20]: Decimal('1.100000000000000088817841970012523233890533447265625')
In [21]: Decimal.from_float(0.1)
Out[21]: Decimal('0.1000000000000000055511151231257827021181583404541015625')

這樣就可以解決我們的困惑與問題啦~

補充:python做浮點數(shù)運算時的坑記錄

很顯然,這個計算結(jié)果是不對的,而且偏離實際值十分遠(yuǎn)。。。。。。。。

太坑人了這。

本來想自動截取計算得到的圖片尺寸,但是這計算結(jié)果,坑害了半天的查找錯誤過程?。。?!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • python二分法查找函數(shù)底值

    python二分法查找函數(shù)底值

    大家好,本篇文章主要講的是python二分法查找函數(shù)底值,感興趣的同學(xué)趕快來看一看吧,對你有用的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Python實現(xiàn)從N個數(shù)中找到最大的K個數(shù)

    Python實現(xiàn)從N個數(shù)中找到最大的K個數(shù)

    這篇文章主要介紹了Python實現(xiàn)從N個數(shù)中找到最大的K個數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python文件和文件夾復(fù)制函數(shù)

    python文件和文件夾復(fù)制函數(shù)

    這篇文章主要為大家詳細(xì)介紹了python文件和文件夾復(fù)制函數(shù)的實現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • python實現(xiàn)的登錄和操作開心網(wǎng)腳本分享

    python實現(xiàn)的登錄和操作開心網(wǎng)腳本分享

    這篇文章主要介紹了python實現(xiàn)的登錄和操作開心網(wǎng)腳本分享,可以登錄開心網(wǎng),登錄后發(fā)送信息等功能,需要的朋友可以參考下
    2014-07-07
  • Python 數(shù)據(jù)可視化pyecharts的使用詳解

    Python 數(shù)據(jù)可視化pyecharts的使用詳解

    這篇文章主要介紹了Python 數(shù)據(jù)可視化pyecharts的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 深入理解Python虛擬機中的反序列化pyc文件

    深入理解Python虛擬機中的反序列化pyc文件

    再這篇文章中我們將主要對?Code?Object?進(jìn)行分析,并且詳細(xì)它是如何被反序列化的,通過本篇文章我們將能夠把握整個?pyc?文件結(jié)構(gòu),感興趣的可以了解一下
    2023-05-05
  • 教你用scrapy框架爬取豆瓣讀書Top250的書類信息

    教你用scrapy框架爬取豆瓣讀書Top250的書類信息

    這篇文章主要介紹了教你用scrapy框架爬取豆瓣讀書Top250的書類信息,文中提供了解決思路和部分實現(xiàn)代碼,需要的朋友可以參考下
    2023-03-03
  • 使用 Django Highcharts 實現(xiàn)數(shù)據(jù)可視化過程解析

    使用 Django Highcharts 實現(xiàn)數(shù)據(jù)可視化過程解析

    這篇文章主要介紹了使用 Django Highcharts 實現(xiàn)數(shù)據(jù)可視化過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • python網(wǎng)絡(luò)爬蟲精解之Beautiful Soup的使用說明

    python網(wǎng)絡(luò)爬蟲精解之Beautiful Soup的使用說明

    簡單來說,Beautiful Soup 是 python 的一個庫,最主要的功能是從網(wǎng)頁抓取數(shù)據(jù),Beautiful Soup 提供一些簡單的、python 式的函數(shù)用來處理導(dǎo)航、搜索、修改分析樹等功能,需要的朋友可以參考下
    2021-09-09
  • python基礎(chǔ)之單分派泛函數(shù)singledispatch

    python基礎(chǔ)之單分派泛函數(shù)singledispatch

    這篇文章主要介紹了python基礎(chǔ)之單分派泛函數(shù)singledispatch問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

桂阳县| 广平县| 山东省| 临海市| 中阳县| 通山县| 平定县| 桓台县| 嘉祥县| 项城市| 江门市| 元阳县| 马龙县| 宁强县| 武隆县| 蒙自县| 盐边县| 濉溪县| 仙游县| 衡山县| 通榆县| 遂昌县| 石屏县| 顺昌县| 秀山| 嘉义县| 双桥区| 方城县| 宣城市| 尚义县| 惠来县| 清河县| 讷河市| 阳西县| 香河县| 岳阳县| 股票| 宜章县| 蓝山县| 兴义市| 高平市|