亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python浮點(diǎn)數(shù)四舍五入問題的分析與解決方法

 更新時(shí)間:2019年11月19日 15:01:19   作者:藝賽旗RPA社區(qū)  
這篇文章主要給大家介紹了關(guān)于Python中浮點(diǎn)數(shù)四舍五入問題的分析與解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

問題

昨天遇到一個(gè)問題,在 6.6045 保留三位小數(shù)時(shí),使用 round() 函數(shù)進(jìn)行計(jì)算,我們希望得到 6.605,然而:

>>> round(6.6045, 3)
6.604

網(wǎng)上有人說,因?yàn)樵谟?jì)算機(jī)里面,小數(shù)是不精確的,例如 1.115 在計(jì)算機(jī)中實(shí)際上是 1.114999999999999991182,所以當(dāng)你對這個(gè)小數(shù)精確到小數(shù)點(diǎn)后兩位的時(shí)候,實(shí)際上小數(shù)點(diǎn)后第三位是 4,所以四舍五入,結(jié)果為 1.11.

這種說法,對了一半。

因?yàn)椴⒉皇撬械男?shù)在計(jì)算機(jī)中都是不精確的。例如 0.125 這個(gè)小數(shù)在計(jì)算機(jī)中就是精確的,它就是 0.125,沒有省略后面的值,沒有近似,它確確實(shí)實(shí)就是 0.125.

但是如果我們在 Python 中運(yùn)行:

>>> round(0.125, 2)
0.12

為什么在這里四舍了?

還有更奇怪的,另一個(gè)在計(jì)算機(jī)里面能夠精確表示的小數(shù) 0.375,我們來看看精確到小數(shù)點(diǎn)后兩位是多少:

>>> round(0.375, 2)
0.38

為什么在這里又五入了?

解析

因?yàn)樵?Python3 里面,round 對小數(shù)的精確度采用了四舍六入五成雙的方式。

如果你寫過大學(xué)物理的實(shí)驗(yàn)報(bào)告,那么你應(yīng)該會(huì)記得老師講過,直接使用四舍五入,最后的結(jié)果可能會(huì)偏高,所以需要使用奇進(jìn)偶舍的處理方法。

例如對于一個(gè)浮點(diǎn)數(shù) a.bcd,需要精確到小數(shù)點(diǎn)后兩位,那么就要看小數(shù)點(diǎn)后第三位:

  • 如果 d 小于 5,直接舍去;
  • 如果 d 大于 5,直接進(jìn)位;
  • 如果 d 等于 5:
    d 后面沒有數(shù)據(jù),且 c 為偶數(shù),那么不進(jìn)位,保留 c
    d 后面沒有數(shù)據(jù),且 c 為奇數(shù),那么進(jìn)位,c 變成 (c + 1)
  • 如果 d 后面還有非 0 數(shù)字,例如實(shí)際上小數(shù)為 a.bcdef,此時(shí)一定要進(jìn)位,c 變成 (c + 1)

關(guān)于奇進(jìn)偶舍,有興趣的朋友可以在維基百科搜索這兩個(gè)詞條:數(shù)值修約和奇進(jìn)偶舍。

所以,round 給出的結(jié)果如果跟設(shè)想的不一樣,那么需要考慮兩個(gè)原因:
你的這個(gè)小數(shù)在計(jì)算機(jī)中能不能被精確儲(chǔ)存?如果不能,那么它可能并沒有達(dá)到四舍五入的標(biāo)準(zhǔn),例如 1.115,它的小數(shù)點(diǎn)后第三位實(shí)際上是 4,當(dāng)然會(huì)被舍去。
如果你的這個(gè)小數(shù)在計(jì)算機(jī)中能被精確表示,那么,round 采用的進(jìn)位機(jī)制是奇進(jìn)偶舍,所以這取決于你要保留的那一位,它是奇數(shù)還是偶數(shù),以及它的下一位后面還有沒有數(shù)據(jù)。

關(guān)于奇進(jìn)偶舍,有興趣的朋友可以在搜索這兩個(gè)詞條:數(shù)值修約和奇進(jìn)偶舍。

回到最開始的問題,對于 6.6045 這個(gè)浮點(diǎn)數(shù),我們在 Scheme 中查看一下它的精確形式:

> (exact 6.6045)
3718002967371055/562949953421312

也就是說它是不能被精確儲(chǔ)存的,大概表現(xiàn)為 6.60449999999999…的形式,因此四舍五入的時(shí)候得到了 6.604。

如何正確進(jìn)行四舍五入

如果要實(shí)現(xiàn)數(shù)學(xué)上的四舍五入,那么就需要使用 decimal 模塊,具體用法參考官方文檔:https://docs.python.org/zh-cn...。
其中 quantize 的函數(shù)原型和文檔說明,提到了可以通過指定 rounding 參數(shù)來確定進(jìn)位方式。如果沒有指定 rounding 參數(shù),那么會(huì)默認(rèn)使用上下文提供的進(jìn)位方式。

現(xiàn)在我們來查看一下默認(rèn)的上下文中的進(jìn)位方式是什么:

>>> from decimal import getcontext
>>> getcontext().rounding
'ROUND_HALF_EVEN'

ROUND_HALF_EVEN 實(shí)際上就是奇進(jìn)偶舍,如果要指定真正的四舍五入,那么我們需要在 quantize 中指定進(jìn)位方式為 ROUND_HALF_UP:

>>> from decimal import Decimal, ROUND_HALF_UP
>>> Decimal('0.125').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
Decimal('0.13')

現(xiàn)在看起來一切都正常了。

有人可能會(huì)進(jìn)一步追問一下,如果 Decimal 接收的參數(shù)不是字符串,而是浮點(diǎn)數(shù)會(huì)怎么樣呢?
來實(shí)驗(yàn)一下:

>>> Decimal(0.125)
Decimal('0.125')

那是不是說明,在 Decimal 的第一個(gè)參數(shù),可以直接傳浮點(diǎn)數(shù)呢?

我們換一個(gè)數(shù)來測試一下:

>>> Decimal(11.245)
Decimal('11.2449999999999992184029906638897955417633056640625')

浮點(diǎn)數(shù) 11.245 和字符串'11.245'傳進(jìn)去以后的結(jié)果居然不一樣。

我們繼續(xù)在文檔中尋找答案:


官方文檔已經(jīng)很清楚地說明了,如果你傳入的參數(shù)為浮點(diǎn)數(shù),并且這個(gè)浮點(diǎn)值在計(jì)算機(jī)里面不能被精確存儲(chǔ),那么它會(huì)先被轉(zhuǎn)換為一個(gè)不精確的二進(jìn)制值,然后再把這個(gè)不精確的二進(jìn)制值轉(zhuǎn)換為等效的十進(jìn)制值。對于不能精確表示的小數(shù),當(dāng)你傳入的時(shí)候,Python 在拿到這個(gè)數(shù)前,這個(gè)數(shù)就已經(jīng)被轉(zhuǎn)成了一個(gè)不精確的數(shù)了。所以雖然參數(shù)傳入的是 11.245,但是 Python 拿到的實(shí)際上是 11.24499999999…

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 詳解從Django Allauth中進(jìn)行登錄改造小結(jié)

    詳解從Django Allauth中進(jìn)行登錄改造小結(jié)

    這篇文章主要介紹了從 Django Allauth 中進(jìn)行登錄改造小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Python和RabbitMQ進(jìn)行消息傳遞和處理方式

    Python和RabbitMQ進(jìn)行消息傳遞和處理方式

    這篇文章主要介紹了Python和RabbitMQ進(jìn)行消息傳遞和處理方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 對python中數(shù)組的del,remove,pop區(qū)別詳解

    對python中數(shù)組的del,remove,pop區(qū)別詳解

    今天小編就為大家分享一篇對python中數(shù)組的del,remove,pop區(qū)別詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • PyTorch中Tensor的維度變換實(shí)現(xiàn)

    PyTorch中Tensor的維度變換實(shí)現(xiàn)

    這篇文章主要介紹了PyTorch中Tensor的維度變換實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • python使用數(shù)字與字符串方法技巧

    python使用數(shù)字與字符串方法技巧

    這篇文章主要介紹了python使用數(shù)字與字符串方法技巧,文章內(nèi)容介紹詳細(xì)具有一的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • python中不能連接超時(shí)的問題及解決方法

    python中不能連接超時(shí)的問題及解決方法

    這篇文章主要介紹了python中不能連接超時(shí)的問題及解決方法,需要的朋友可以參考下
    2018-06-06
  • Mac PyCharm中的.gitignore 安裝設(shè)置教程

    Mac PyCharm中的.gitignore 安裝設(shè)置教程

    這篇文章主要介紹了Mac PyCharm中的.gitignore 安裝設(shè)置教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Python3實(shí)現(xiàn)個(gè)位數(shù)字和十位數(shù)字對調(diào), 其乘積不變

    Python3實(shí)現(xiàn)個(gè)位數(shù)字和十位數(shù)字對調(diào), 其乘積不變

    這篇文章主要介紹了Python3實(shí)現(xiàn)個(gè)位數(shù)字和十位數(shù)字對調(diào), 其乘積不變,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python3中No module named _ssl的問題解決

    python3中No module named _ssl的問題解決

    本文主要介紹了python3中No module named _ssl的問題解決,這個(gè)錯(cuò)誤表示Python導(dǎo)入_ssl模塊時(shí)失敗,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 解析Sentry?Relay?二次開發(fā)調(diào)試

    解析Sentry?Relay?二次開發(fā)調(diào)試

    這篇文章主要介紹了Sentry?Relay?二次開發(fā)調(diào)試簡介,集成測試要求?Redis?和?Kafka?在其默認(rèn)配置中運(yùn)行,獲取所有必需服務(wù)的最便捷方式是通過?sentry?devservices,這需要最新的?Sentry?開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-03-03

最新評(píng)論