欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python浮點(diǎn)數(shù)取整、格式化和NaN處理的操作方法

 更新時(shí)間:2022年05月23日 08:35:01   作者:orion-orion  
這篇文章主要介紹了Python浮點(diǎn)數(shù)取整、格式化和NaN處理的操作方法,本文較詳細(xì)介紹了取整的三種方法,格式化浮點(diǎn)數(shù)輸出的示例代碼詳解,感興趣的朋友跟隨小編一起看看吧

強(qiáng)轉(zhuǎn)int類(lèi)型會(huì)直接對(duì)浮點(diǎn)數(shù)的小數(shù)部分進(jìn)行截?cái)啵o(wú)論是正還是負(fù))。還有一種方法是math.ceil和math.floor。無(wú)論是正數(shù)還是負(fù)數(shù),都遵循:ceil往數(shù)軸正方向取整,floor往數(shù)軸負(fù)方向取整。round原型為round(value, ndigits),可以將一個(gè)浮點(diǎn)數(shù)取整到固定的小數(shù)位。該函數(shù)對(duì)正數(shù)和負(fù)數(shù)都采取就近取整原則,而當(dāng)某個(gè)值恰好等于兩個(gè)整數(shù)間一半時(shí),取整操作會(huì)取到離該值最近的那個(gè)偶數(shù)。

1. 取整的三種方法

1.1 強(qiáng)轉(zhuǎn)int類(lèi)型

這種方法會(huì)直接對(duì)浮點(diǎn)數(shù)的小數(shù)部分進(jìn)行截?cái)啵o(wú)論是正還是負(fù))。

print(int(2.7)) # 2
print(int(-2.7)) # -2

1.2 采用math.ceil和math.floor

這種方法的取整規(guī)則如下圖所示:

可以看到無(wú)論是正數(shù)還是負(fù)數(shù),都遵循:ceil往數(shù)軸正方向取整,floor往數(shù)軸負(fù)方向取整。實(shí)例如下:

print(math.ceil(-1.27)) # -1
print(math.floor(-1.27)) # -2
print(math.ceil(1.27)) # 2
print(math.floor(1.27)) # 1

1.3 采用round

round原型為round(value, ndigits),可以將一個(gè)浮點(diǎn)數(shù)取整到固定的小數(shù)位。該函數(shù)對(duì)正數(shù)和負(fù)數(shù)都采取就近取整原則,而當(dāng)某個(gè)值恰好等于兩個(gè)整數(shù)間一半時(shí),取整操作會(huì)取到離該值最近的那個(gè)偶數(shù)。像1.5和2.5這樣的值都會(huì)取整到2。示例如下:

print(round(1.23, 0)) # 1.0
print(round(1.23, 1)) # 1.2
print(round(1.27, 1)) # 1.3
print(round(-1.27, 1)) # -1.3
print(round(1.25361, 3)) # 1.254
print(round(1.5, 0)) # 2.0
print(round(2.5, 0)) # 2.0

傳遞給round()參數(shù)ndigits可以是負(fù)數(shù),這種情況下回相應(yīng)取整到十位、百位、千位:

a = 1627731
print(round(a, -1)) # 1627730
print(round(a, -2)) # 1627700
print(round(a, -3)) # 1628000

2. 格式化浮點(diǎn)數(shù)輸出

注意對(duì)值輸出時(shí)別把取整和格式化操作混為一談。如果只是將數(shù)值以固定位數(shù)輸出,一般是用不著round()的,只要在用format格式化時(shí)指定所需要的精度即可(format()格式化操作會(huì)根據(jù)round()的規(guī)則進(jìn)行取整,最終返回一個(gè)字符串類(lèi)型)。

x = 1234.56789
s = format(x, "0.2f")
print(type(s), format(x, "0.2f")) # <class 'str'> 1234.57

除了取整到固定小數(shù)位,format()還具有許多格式化功能,如格式化輸出對(duì)齊,增加千分位分隔符等。實(shí)際上面的0.2f就表示至少對(duì)齊到0個(gè)字符(相當(dāng)于沒(méi)有對(duì)齊操作),并保留兩位小數(shù)。

小提示:.2f也表示至少對(duì)齊到0個(gè)字符(默認(rèn)是0),并保留兩位小數(shù),
0.2f二者是等效的。

更多示例如下:

# 往右調(diào)整以對(duì)齊到10個(gè)字符
print(format(x, ">10.1f")) #     1234.6
# 往右調(diào)整以對(duì)齊到10個(gè)字符
print(format(x, "<10.1f")) # 1234.6    
# 居中以對(duì)齊到10個(gè)字符
print(format(x, "^10.1f")) #   1234.6  
# 增加千位分隔符
print(format(x, ",")) # 1,234.56789
# 增加千位分隔符并保存到1位小數(shù)
print(format(x, "0,.1f")) # 1,234.6

如果想使用科學(xué)計(jì)數(shù)法,只要把f改成eE即可:

print(format(x, "e")) # 1.234568e+03
print(format(x, "0.2E")) # 1.23E+03

此外,我們還可以利用字符串的translate()方法交換不同的分隔符:

swap_separators = {ord("."):",", ord(","):"."}
print(format(x, ",").translate(swap_separators)) # 1.234,56789

最后,我們這里提一下,調(diào)用字符串的.format()函數(shù)和單獨(dú)調(diào)用format()函數(shù)可以達(dá)到相同的效果,如:

print("value is {:0.3f}".format(x)) # value is 1.235
print("The value is {:0,.2f}".format(x)) # The value is 1,234.57

當(dāng)然我們也可以使用%操作符來(lái)對(duì)數(shù)值做格式化處理,如:

print("%.2f" % x)
print("%10.1f" % x)
print("%-10.1f" % x)

這種格式化操作雖然可行,但是比起更加現(xiàn)代化的format()方法,這種方法就顯得不是那么強(qiáng)大了。如用%操作符來(lái)格式化數(shù)值時(shí),有些功能就沒(méi)法得到支持了(如添加千位分隔符)。

3. 執(zhí)行精確的小數(shù)計(jì)算

我們?cè)诘谝徊糠纸榻B了round()函數(shù),我們有可能會(huì)企圖用浮點(diǎn)取整的方式來(lái)“修正”精度上的問(wèn)題,如:

a = 2.1
b = 4.2
c = a + b
print(c) # 6.300000000000001
print(c==6.3) # False
print(round(c, 2)) # 6.3 企圖這樣修正精度(???)

對(duì)大部分浮點(diǎn)數(shù)應(yīng)用程序(包括科學(xué)計(jì)算與機(jī)器學(xué)習(xí))來(lái)說(shuō),一般都不必(或者所不推薦)這么做。雖然Python的浮點(diǎn)運(yùn)算會(huì)引入一些小誤差,但這些誤差實(shí)際上是底層CPU的浮點(diǎn)運(yùn)算單元和IEEE 754浮點(diǎn)算數(shù)標(biāo)準(zhǔn)的一種“特性”。由于Python的浮點(diǎn)數(shù)類(lèi)型保存的數(shù)據(jù)采用的是原始保存形式,因此只要代碼中用到了float實(shí)例,那就無(wú)法避免這樣的誤差。

如果避免出現(xiàn)誤差的行為非常重要(比如在金融應(yīng)用中),那么可以考慮使用decimal模塊。事實(shí)上在用Python做數(shù)據(jù)庫(kù)庫(kù)接口時(shí)經(jīng)常碰到Decimal對(duì)象——當(dāng)訪問(wèn)金融數(shù)據(jù)時(shí)尤其如此。我們通過(guò)使用Decimal對(duì)象解決上述問(wèn)題:

from decimal import Decimal
a = Decimal('4.2')
b = Decimal('2.1')
print(type(a + b), a + b) # <class 'decimal.Decimal'> 6.3
print((a + b) == Decimal('6.3')) # True

這么做看起來(lái)似乎有點(diǎn)怪異(將數(shù)字以字符串的形式來(lái)指定)。但是Decimal對(duì)象能夠以任何期望的方式來(lái)工作(支持所有常見(jiàn)的數(shù)學(xué)操作)。如果要將它們打印出來(lái)或者在字符串格式化函數(shù)中使用,它們看起來(lái)就和普通數(shù)字一樣。它們也可以和普通int、float類(lèi)型混合操作(最后會(huì)統(tǒng)一強(qiáng)轉(zhuǎn)為Decimal類(lèi)型):

print(type(a + 1), a + 1) # <class 'decimal.Decimal'> 5.2

但是需要注意的是不要將其與普通float類(lèi)型直接進(jìn)行比較:

print((a + b) == 6.3) # False

decimal模塊的強(qiáng)大之處在于在計(jì)算過(guò)程中靈活地控制數(shù)字的位數(shù)和四舍五入,如我們可以創(chuàng)建一個(gè)本地的上下文環(huán)境然后修改精度的設(shè)定,如:

from decimal import localcontext
a = Decimal("1.3")
b = Decimal("1.7")
print(a/b) # 0.7647058823529411764705882353
with localcontext() as ctx:
    ctx.prec = 3
    print(a/b) # 0.765 

with localcontext() as ctx:
    ctx.prec = 50
    print(a/b) # 0.764705882352941176470588235294117647058823529

不過(guò)還是我們上面所說(shuō)的,如果我們處理的是科學(xué)或工程類(lèi)型的問(wèn)題,那么更常見(jiàn)的做法是直接使用普通的float浮點(diǎn)類(lèi)型。首先,在真實(shí)世界中極少有東西需要計(jì)算到小數(shù)點(diǎn)后17位(float提供17位的精度),因此在計(jì)算中引入的微小誤差不足掛齒;其次,原生的float浮點(diǎn)數(shù)運(yùn)算性能要快許多——如果要執(zhí)行大量計(jì)算,性能問(wèn)題就顯得很重要了。

在使用float類(lèi)型時(shí),我們同樣還需要對(duì)類(lèi)似相減抵消(substraction cancellation)以及把大數(shù)和小數(shù)加載一起的情況多加小心:

nums = [1.23e+18, 1, -1.23e+18]
print(sum(nums)) # 0.0

使用Decimal對(duì)象當(dāng)然可以解決此問(wèn)題。不過(guò)在不動(dòng)用Decimal對(duì)象的情況下,我們可以使用math.fsum()以更精確的實(shí)現(xiàn)來(lái)解決:

import math
print(math.fsum(nums)) # 1.0

但對(duì)于其它復(fù)雜的數(shù)值算法,我們就需要研究算法本身,理解其誤差傳播(error propagation)了,這屬于數(shù)值分析的研究范疇。在數(shù)值分析中數(shù)學(xué)家研究了大量數(shù)值算法,其中一些算法的誤差處理能力優(yōu)于其它算法,詳情可以參見(jiàn)我的數(shù)值計(jì)算專(zhuān)欄《orion-orion:數(shù)值計(jì)算》,此處不再詳述。

4. 無(wú)窮大、負(fù)無(wú)窮大和NaN的判斷測(cè)試

在實(shí)際項(xiàng)目中我們需要對(duì)浮點(diǎn)數(shù)的無(wú)窮大、負(fù)無(wú)窮大或NaN(not a number)進(jìn)行判斷測(cè)試。在Python中沒(méi)有特殊的語(yǔ)法來(lái)表示這些特殊的浮點(diǎn)值,但是它們可以通過(guò)float來(lái)創(chuàng)建:

a = float("inf")
b = float("-inf")
c = float("nan")
print(a, b, c) # inf -inf nan

要檢查是否出現(xiàn)了這些值,可以使用math.isinf()math.isnan()函數(shù):

print(math.isinf(a)) # True
print(math.isnan(c)) # True

這些特殊浮點(diǎn)數(shù)的詳細(xì)信息可以參考IEEE 754規(guī)范。但是我們這里有幾個(gè)棘手的問(wèn)題需要搞清楚,尤其是設(shè)計(jì)比較操作和操作符時(shí)可能出現(xiàn)的問(wèn)題。

無(wú)窮大值在數(shù)學(xué)計(jì)算中會(huì)進(jìn)行傳播,如:

a = float("inf")
print(a + 45) # inf
print(a * 10) # inf
print(10/a) # 0.0

但是,某些關(guān)于無(wú)窮大值特定的操作會(huì)導(dǎo)致未定義的行為并產(chǎn)生NaN的結(jié)果,例如:

a = float("inf")
print(a/a) # nan
b = float("-inf")
print(a + b) # nan

NaN會(huì)通過(guò)所有的操作進(jìn)行傳播,且不會(huì)引發(fā)任何異常,如:

c = float("nan")
print(c + 23) # nan
print(c / 2) # nan
print(c + 2) # nan

有關(guān)NaN,一個(gè)微妙的特性是他們?cè)谧霰容^時(shí)從不會(huì)被判定為相等,如:

c = float("nan")
d = float("nan")
print(c == d) # False
print(c is d) # False

正因?yàn)槿绱耍ㄒ话踩珯z測(cè)NaN的方法是使用math.isnan()。

參考

[1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. " O'Reilly Media, Inc.", 2015.

[2] https://stackoverflow.com/questions/15765289/what-is-the-difference-between-0-2lf-and-2lf-as-printf-placeholders

[3] https://docs.python.org

到此這篇關(guān)于Python浮點(diǎn)數(shù)取整、格式化和NaN處理的操作方法的文章就介紹到這了,更多相關(guān)Python浮點(diǎn)數(shù)取整內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Python的Zato發(fā)送AMQP消息的教程

    使用Python的Zato發(fā)送AMQP消息的教程

    這篇文章主要介紹了使用Python的Zato發(fā)送AMQP消息的教程,主要是基于一些Zato的圖形化界面進(jìn)行操作,需要的朋友可以參考下
    2015-04-04
  • python爬蟲(chóng)請(qǐng)求頭設(shè)置代碼

    python爬蟲(chóng)請(qǐng)求頭設(shè)置代碼

    在本篇文章里小編給大家整理的是一篇關(guān)于python爬蟲(chóng)請(qǐng)求頭如何設(shè)置內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-07-07
  • 教你在pycharm中使用tensorflow的方法

    教你在pycharm中使用tensorflow的方法

    當(dāng)前使用的是anaconda的3.8版本,無(wú)法正常下載tensorflow包,需要構(gòu)建虛擬環(huán)境使用3.7及以下的解釋器才可以,如何解決這個(gè)問(wèn)題呢,下面小編給大家?guī)?lái)了如何在pycharm中使用tensorflow,感興趣的朋友參考下吧
    2021-11-11
  • python3 cvs將數(shù)據(jù)讀取為字典的方法

    python3 cvs將數(shù)據(jù)讀取為字典的方法

    今天小編就為大家分享一篇python3 cvs將數(shù)據(jù)讀取為字典的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • Python學(xué)習(xí)之時(shí)間包使用教程詳解

    Python學(xué)習(xí)之時(shí)間包使用教程詳解

    本文主要介紹了Python中的內(nèi)置時(shí)間包:datetime包?與?time包?,通過(guò)學(xué)習(xí)時(shí)間包可以讓我們的開(kāi)發(fā)過(guò)程中對(duì)時(shí)間進(jìn)行輕松的處理,快來(lái)跟隨小編一起學(xué)習(xí)一下吧
    2022-03-03
  • flask之郵件發(fā)送的實(shí)現(xiàn)示例

    flask之郵件發(fā)送的實(shí)現(xiàn)示例

    Flask-Mail是一個(gè)處理電子郵件發(fā)送的擴(kuò)展,它提供了簡(jiǎn)單且易于使用的API,可以方便地發(fā)送電子郵件,本文就來(lái)介紹一下flask之郵件發(fā)送的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-12-12
  • python讀取nc數(shù)據(jù)并繪圖的方法實(shí)例

    python讀取nc數(shù)據(jù)并繪圖的方法實(shí)例

    最近項(xiàng)目中需要處理和分析NC數(shù)據(jù),所以下面這篇文章主要給大家介紹了關(guān)于python讀取nc數(shù)據(jù)并繪圖的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • python 找出list中最大或者最小幾個(gè)數(shù)的索引方法

    python 找出list中最大或者最小幾個(gè)數(shù)的索引方法

    今天小編就為大家分享一篇python 找出list中最大或者最小幾個(gè)數(shù)的索引方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • python中常見(jiàn)的5種框架解讀

    python中常見(jiàn)的5種框架解讀

    這篇文章主要介紹了python中常見(jiàn)的5種框架,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Python3多線程版TCP端口掃描器

    Python3多線程版TCP端口掃描器

    這篇文章主要為大家詳細(xì)介紹了Python3多線程版TCP端口掃描器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論