你確定你真的學了Python?

2021-02-19 極客夜讀





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

啥問題呢?請看題:

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

但是如果你用 python 去執行一下,會發現結果跟你想的不太一樣,如下圖:

>>> 1.1 - 1
0.10000000000000009

這樣大家是不是發現了什麼問題?是的,浮點數在運算過程中並沒有保證完全精確,是什麼原因導致了這種現象呢?很多朋友就會竊喜:「這不就是 Python 的 bug 嘛~」

但實際上,這並不是 Python 中的 bug ,它和計算機硬體中如何處理浮點數有關。浮點數在計算機硬體中以二進位的形式存在,但是我們現在看到的都是十進位,而十進位的浮點數不能都完全精確的表示為二進位小數。

就比如說我們在十進位數中無法用小數精確表示 1/3 一樣,在二進位數中也無法用小數精確表示 1/10。顯然這樣子的說明並沒有十進位中的 1/3 那麼直觀,接下來我們嘗試去計算一下二進位中的 1/10 :

十進位的整數位是二進位的整數位,十進位的小數位是二進位數的小數位。那現在我們拿到0.1

整數部分為0

小數部分為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

有沒有發現?在二進位下,1/10 是一個無限循環小數:0.00011001100110011…,顯然這樣的表示形式無法精確的表示浮點數,最終的結果是近似 1/10 。在使用 IEEE-754 浮點運算標準的計算機硬體上,Python 的浮點數映射為 IEEE-754 雙精度浮點數,共包含 53 位精度(這裡指的是二進位),在這個範圍下,這個最接近 1/10 的結果是:3602879701896397/2∗∗55

這表示在計算機硬體中,1/10 的真實十進位數值為:0.1000000000000000055511151231257827021181583404541015625

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

四捨五入進行解決

在 python 中,使用 round(number[, ndigits]) 來進行四捨五入,其中 ndigits 表示保留幾位小數,默認為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

上面代碼符合我們四捨五入的預期結果,但是不要著急,我們接著往下看:

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)會直接進為1.2,但是此時並沒有,而是變為了1.1。這是為什麼呢?

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

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

看到這個結果,我們就恍然大悟,為什麼看到的結果會是1.1了。

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

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

這個規則,用我們熟悉的話來說即為「 四捨六入五成雙 」。

使用decimal進行浮點數的精確計算

那我們在 Python 中怎麼進行精確的浮點數計算呢,Python 標準庫為我們提供了decimal 這個模塊來解決這個問題,decimal 常用於需要精確處理浮點數的場合,比如銀行帳戶金額、貨幣加減等。

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')

同樣,我們可以使用它來查看對於不能精確表示的浮點數在計算機內部的具體數值:

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

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

這樣就可以解決我們的困惑與問題啦~oh ye!如果覺得有收穫的話,歡迎點讚關注加分享奧!

相關焦點

  • 學習Python對辦公真的有用嗎?用經驗告訴你答案
    如果用8個月來學寫作或者進修相關的專業知識,會不會我的工作能力已經大幅提高了?其實這裡不能怪python機構的鍋,從商業角度來說,他們售賣python課程,進行一定程度的營銷和推廣是沒問題的,這個我可以理解。這裡要特別講明一下,有些python機構賣的課其實很淺顯,質量參差不齊,這一點需要小夥伴們仔細辨別。他們把信息展現給你,學不學其實是我們來決定的。
  • 編程界新晉「網紅」Python到底是什麼?學Python真的有用嗎?
    如果你的工作大部分都是重複性的操作,那麼你的工作則很有可能在未來某天被計算機所替代。當你的工作被新的技術一步一步取代,而你卻對它一無所知。等到你的工作完全被新的技術以及懂技術的人取代之時,你會發現一切已經來不及。
  • Python已是曇花一現,但你卻還在堅持嗎?看看他們的理由
    Python已是曇花一現,你為什麼還在堅持呢?Python,是一門最適合人工智慧的程式語言,並且,這門語言十分適合新手學習,正因為如此,讓發展了近三十年的python,在最近幾年火爆全網。可為什麼說python已是曇花一現呢?因為有人找不到工作。
  • 人生苦短,我用Python,那麼問題來了,普通人要學python嗎?
    最近在教育店集中地兒瞎晃悠,震驚的發現這年頭六歲娃兒都要學編程了,當時我的表情是這樣的。回到家抱著冷嘲熱諷的心,我特意百度搜索了下新聞,結果我的表情是這樣的:1、Python將納入浙江省高考!從 2018 年起浙江省信息技術教材程式語言將會更換為 Python。
  • 普通人學Python有意義嗎?學Python有前途嗎?-開課吧Python
    Pythonpython憑藉著第三方庫數量的龐大,其幾乎可以說是萬能的,對於普通人來說,數據表格excel基本上都有需要製作,而有一些編程基礎的,就可以使用庫openpyxl來實現excel表格的自動處理和生成,同時除了excel之外,針對word,ppt等python都有對應的庫。
  • Python2 已終結,入手Python 3,你需要這30個技巧
    這篇教程有 30 個你會喜歡的方法。勤勞的程式設計師們,這裡有 30 條使用 Python 時實用的建議和小技巧。你可以把讀這篇文章當做工作間隙的小憩,而且我保證你學到的東西會跟工作時一樣多。1.,這樣 bug 量會大大減少下面展示了一個實用的數據類例子:想更深入的了解數據類,可以參考:https://realpython.com/python-data-classes/8.
  • 4種方法告訴你!天津0基礎如何學python培訓?
    小夥伴們應該都知道豆瓣網吧,這個真的很強大了,我們一般看的電影評分較高的就會是優zhi電影,這其中豆瓣可是貢獻了不少,看來是有很多小夥伴都很相信豆瓣的評分的,但小夥伴們知道豆瓣是被什麼開發出來的嗎?就是我們的python程式設計師,python可以用來做很多事情,比如:網絡爬蟲、數據分析等。
  • 你確定,你真的認識「葫蘆蘚」嗎?
    圖1:葫蘆蘚配子體「葫蘆娃,葫蘆娃,一根藤上七個瓜,風吹雨打都不怕,啦啦啦……」,當這首歌在耳邊響起,你是否能跟隨著一起哼唱起來呢?動畫片《葫蘆兄弟》你是否觀看過?這可是曾經風靡一時的經典剪紙動畫片哦,如果你還沒看過,快讓爸爸媽媽陪你一起看看吧。在動畫片中,七個葫蘆娃每人頭上都頂著一個不同顏色的彩葫蘆,超級惹人喜愛。
  • python基礎教程之python是什麼?
    如果你聽說過TIOBE排行榜,你就能知道程式語言的大致流行程度。這是最近10年最常用的10種程式語言的變化圖:python是什麼--python的功能總的來說,這幾種程式語言各有千秋。當你用一種語言開始作真正的軟體開發時,你除了編寫代碼外,還需要很多基本的已經寫好的現成的東西,來幫助你加快開發進度。比如說,要編寫一個電子郵件客戶端,如果先從最底層開始編寫網絡協議相關的代碼,那估計一年半載也開發不出來。
  • Python爬蟲學到什麼程度就可以去找工作了?
    有朋友在群裡和大家討論,問的最多的問題就是,python 爬蟲學到什麼程度可以去找工作了,關於這點,和大家分享下我的理解。去招聘網上看看需求都有哪些,直接做個拉勾網爬蟲(有需要的私信)出結果了:仔細看看,我們可以得出以下幾點:1、 python 不是唯一可以做爬蟲的,很多語言都可以,
  • 入門Python,這些JupyterNotebook技巧就是你必須學的
    此系列文章收錄在公眾號(建議按順序閱讀本系列文章) : 數據大宇宙 > Python > 工具轉發本文並私信我"python",即可獲得Python資料以及更多系列文章(持續更新的)Python數據人你竟然不會用JupyterNotebook!
  • 《小灰教你零基礎學python》-Python入門語言
    程式語言有很多,咱們就學簡單強大的python即可。三、python程式語言介紹Python是荷蘭人吉多·范羅蘇姆(Guido van Rossum)在1989年聖誕節期間開發的一門解釋性的腳本語言,什麼是解釋性的語言,大家可以參照百度百科(
  • python是什麼,python能幹什麼,為什麼大家都學pyhon一起來看看吧
    相信大家如果經常上網,就會看到各種學python的教程,那麼python究竟是什麼意思,學會了可以用來幹什麼那,我們一起來看一下吧。首先大家要明白python是一種跨平臺的程式語言,python編程的特點易讀、易維護,所以被大量的用戶所歡迎,python最大的特點是開發速度快,因為編程開發效率一直很低,python有很多第三方庫,所以開發起來事半功倍,很流行的一句話,人生苦短,我學python,可謂是把python特點完整的詮釋出來。
  • python是什麼:Python相關內容了解
    今天來聊聊一篇關於python是什麼:Python相關內容了解的文章,現在就為大家來簡單介紹下python是什麼:Python相關內容了解,希望對各位小夥伴們有所幫助。當你用一種語言開始作真正的軟體開發時,你除了編寫代碼外,還需要很多基本的已經寫好的現成的東西,來幫助你加快開發進度。比如說,要編寫一個電子郵件客戶端,如果先從最底層開始編寫網絡協議相關的代碼,那估計一年半載也開發不出來。
  • 不學Python哪來的月入過萬?
    學什麼Python,小學生學的! Python這麼簡單,還要學嗎 ?看到這些評論也讓我一度懷疑Python到底值不值得學? 我們今天就來說一說到底Python值不值得學呢!#python就拿你來說,畢業來我們公司實習,工資大概在4000左右,但如果你會Python工資可能就有6000~7000不等,我才意識到原來會一門專業技能作用這麼大!回來之後,姐姐每天都有監督我學習,我自己也逐漸從小白進階了。即將畢業工作的我也有了工作的底氣。半路出家不可怕,可怕的是半途而廢,學習固然枯燥無味,可我們也要在玻璃裡面找糖不是麼。
  • 零基礎學python,自學難度大麼?
    python自學難度,這個要看你是否有基礎,如果有,那就很簡單;零基礎自學相對要花更多的時間,難度說高不高,重在堅持。,基礎是最難打的,實際就是自己的方向沒有確定好,最開始是選擇自動化運維的方向,後來又轉向去學人工智慧,這個人工智慧的課程就包含了WEB開發的前後端,爬蟲,資料庫,算法,網絡編程,數據可視化等;因為要學的太多,堅持就非常重要。
  • 如何自學成 Python 大神?這裡有些建議
    如果你真的想要高效地學習 Python,那就需要掌握如何過濾網上的垃圾教程資源的技能,並從其他有經驗的程式設計師或在線編程社區中獲得幫助。倘若你沒有任何編程知識,或者知之甚少,從一張白紙起步,或許會更容易一些。
  • Biopython —— 你不知道的 NCBI 訪問方式
    介紹Biopython 是由 Python 編寫的一組免費可用的計算生物學工具,解決一些生物信息學需求。Biopython 致力於通過創造高質量和可重複利用的 Python 模塊及類,使 Python 在生物信息學中的應用變得更加容易。
  • 成都Python培訓周期多久
    成都python培訓哪個更專業? Python的設計目標之一是使代碼具有很高的可讀性。它被設計成使用標點符號和其他語言中常用的英語單詞,使代碼看起來整潔美觀。現在成都有很多python培訓學校。
  • 序列比對在biopython中的處理
    序列比對是生物信息學分析中的常見任務,包含局部比對和全局比對兩大算法,局部比對最經典的代表是blast, 全局比對則用於多序列比對。在biopython中,支持對序列比對的結果進行讀寫,解析,以及運行序列比對的程序。