python中decimal模塊的用法
查看python3.4.1文檔,發(fā)現(xiàn)對于decimal模塊的講解非常多,由此可見其功能也很強(qiáng)大(下面算是把我認(rèn)為比較重要的半翻譯半學(xué)習(xí)吧~)。文檔關(guān)于decimal模塊的總解釋是Decimal fixed point and floating point arithmetic,我理解的是固定小數(shù)點(diǎn)和浮點(diǎn)運(yùn)算。頭加上from decimal import * 即可調(diào)用decimal模塊中的內(nèi)容。
1. Decimal類型的優(yōu)點(diǎn)
Decimal類型是在浮點(diǎn)類型的基礎(chǔ)上設(shè)計(jì)的,但是它在幾個(gè)地方上要優(yōu)于floating point:
1)Decimal類型可以非常精確地在計(jì)算機(jī)中存儲(chǔ),而學(xué)過c++的都知道,浮點(diǎn)型在計(jì)算機(jī)中是無法精確存儲(chǔ)的,比如1.1和2.2在計(jì)算機(jī)中存儲(chǔ)后,運(yùn)算(1.1+2.2)表達(dá)式的值結(jié)果會(huì)是3.3000000000000003;Decimal類型則不會(huì)出現(xiàn)這種情況。同樣,由于無法精確存儲(chǔ),浮點(diǎn)型也就無法精確計(jì)算(相對于Decimal類型),可以再測試(0.1+0.1+0.1-0.3)兩種類型的計(jì)算結(jié)果。
2)Decimal類型會(huì)自動(dòng)保留小數(shù)點(diǎn)后面不需要的0,以與輸入的精度相匹配,比如下面小程序中的例子:浮點(diǎn)型的1.20+1.30結(jié)果是2.5;而Decimal類型結(jié)果是2.50,這樣貌似比較人性化。
3)Decimal類型可以根據(jù)需要自己設(shè)置小數(shù)點(diǎn)后精度。通過getcontext().prec = x (x為你想要的精度來設(shè)置,getcontext()函數(shù)下面再詳細(xì)介紹)。
4)Decimal類型有很強(qiáng)的管理功能,它能夠根據(jù)需要設(shè)置,來控制輸出的格式,得到或者忽略某類錯(cuò)誤(如除0,可以設(shè)置忽略它,而得到一個(gè)Infinity的Decimal值)。
#difference between float and decimal print(1.1+2.2) #3.3000000000000003 print (Decimal('1.1')+Decimal('2.2')) #3.3 print (0.1+0.1+0.1-0.3) #5.551115123125783e-17 print (Decimal('0.1')+Decimal('0.1')+Decimal('0.1')-Decimal('0.3')) # 0.0 print (1.20+1.30) #2.5 print (Decimal('1.20')+Decimal('1.30')) #2.50
需要注意的是,Decimal()的構(gòu)造中如果是小數(shù)或字符的話,需要加上單引號;如果為整數(shù),則不需要。
2. decimal模塊的構(gòu)成
文檔說,decimal模塊主要由三部分構(gòu)成:the decimal number ,the context of arithmetic ,signals 。
1)decimal number是不可改變的常量,它也不會(huì)截取小數(shù)點(diǎn)后多余的0;除了正常的數(shù)外, 它還包括'Infinity','-Infinity','NaN'等數(shù)。
2)the context of arithmetic是當(dāng)前計(jì)算環(huán)境的一些參數(shù),包括精度位數(shù)prec,舍棄位數(shù)規(guī)則rounding,指數(shù)的最大值最小值Emin、Emax,科學(xué)計(jì)數(shù)法e的大小寫Capitals,指數(shù)是否超出范圍clamped,運(yùn)算結(jié)果的標(biāo)志flags,哪些操作要觸發(fā)traps等。
3)signals是在運(yùn)算過程中產(chǎn)生的一些狀態(tài),這些狀態(tài)可以根據(jù)需要用來提示、忽略、報(bào)錯(cuò)等。
signals和flags、traps是對應(yīng)的,假設(shè)運(yùn)算過程中產(chǎn)生了除0這樣一個(gè)狀態(tài),那么flags中就會(huì)產(chǎn)生一個(gè)DivisionByZero為1這樣的信息,接著如果在traps中包含這個(gè)操作,那么python就會(huì)報(bào)個(gè)異常出來。這樣一個(gè)處理機(jī)制,可以人為的設(shè)置自己需要的信息或異常提示,而把另外一些忽略。
3. context
可以用getcontext()函數(shù)得到當(dāng)前運(yùn)算環(huán)境的參數(shù),直接打印 print (get context()),以我的為例子
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, Overflow, DivisionByZero])
其中,prec精度為28,是默認(rèn)值,可以通過getcontext().prec = 10這樣來設(shè)置自己想要的精度;rounding的規(guī)則是ROUND_HALF_EVEN (具體下面介紹),此外還有其他一些規(guī)則,感興趣的可以查閱文檔或自己測試;traps數(shù)組表明當(dāng)前如果出現(xiàn)這三種狀態(tài)會(huì)報(bào)異常。當(dāng)然,其中的參數(shù)都可以自己修改。
值得一提的是,精度值的修改只在運(yùn)算中才會(huì)體現(xiàn)出來,比如精度是5,輸入Decimal(’1.222222222‘),輸出仍然是這個(gè)數(shù);但是Decimal('1.222222222') + Decimal('1.11111111') 的結(jié)果精度就為6了。
除了可以通過getcontext().prec這樣來修改context的參數(shù),還可以使用setcontext()來一次性設(shè)置context。如下:
mycontext = Context(prec=18, rounding=ROUND_HALF_DOWN) setcontext(mycontext)
這里再學(xué)習(xí)一個(gè)比較有用的函數(shù)quantize(),當(dāng)我們希望在運(yùn)算過程中保持較高的精度,而在結(jié)果中以某種方式保留幾位小數(shù)時(shí)可以用這個(gè)函數(shù),下面是官網(wǎng)文檔的示例:
Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN) Decimal('7.32') #result Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP) Decimal('8') #result
4. Signals
decimal模塊中提供了10種signals,下面簡單介紹一下:
1)Clamped:越界,指數(shù)超出Emin或Emax范圍;如果發(fā)生,則會(huì)在小數(shù)部分添加0來表示;
2)DecimalException;
3)DivisionByZero:在除法運(yùn)算中出現(xiàn),除數(shù)為0;如果不捕捉該錯(cuò)誤,則返回Infinity或-Infinity;
4)Inexact:不精確,使用round函數(shù)舍棄的小數(shù)部分中包含除0以外的數(shù)字;
5)InvalidOperation:無效計(jì)算或計(jì)算無意義,比如兩個(gè)無窮大相減等;如果不捕捉該錯(cuò)誤,則返回NaN(Not a Number);
6)Overflow:在round后指數(shù)超出Emax范圍,如果不捕捉,則根據(jù)round規(guī)則來判斷返回什么值;
7)Rounded:如果round操作舍棄了小數(shù),不管是不是0,都發(fā)生;如果不捕捉,則返回 值未改變;
8)Subnormal:指數(shù)值過?。蝗绻徊蹲?,則返回 值不變;
9)Underflow:指數(shù)值太小,且round操作向0逼近;
10)FloatOperation:如果不捕捉,則混合float型和Decimal型的操作可以執(zhí)行;如果捕捉,則只有相等判斷和顯式轉(zhuǎn)換可以執(zhí)行,其余的都報(bào)錯(cuò)。
5. Round類型
Decimal中大致有以下幾種類型,做簡單介紹一下,如有錯(cuò)誤,希望指正:
1)ROUND_UP:舍棄小數(shù)部分非0時(shí),在前面增加數(shù)字,如 5.21 -> 5.3;
2)ROUND_DOWN:舍棄小數(shù)部分,從不在前面數(shù)字做增加操作,如5.21->5.2;
3)ROUND_CEILING:如果Decimal為正,則做ROUND_UP操作;如果Decimal為負(fù),則做ROUND_DOWN操作;
4)ROUND_FLOOR:如果Decimal為負(fù),則做ROUND_UP操作;如果Decimal為正,則做ROUND_DOWN操作;
5)ROUND_HALF_DOWN:如果舍棄部分>.5,則做ROUND_UP操作;否則,做ROUND_DOWN操作;
6)ROUND_HALF_UP:如果舍棄部分>=.5,則做ROUND_UP操作;否則,做ROUND_DOWN操作;
7)ROUND_HALF_EVEN:如果舍棄部分左邊的數(shù)字是奇數(shù),則做ROUND_HALF_UP操作;若為偶數(shù),則做ROUND_HALF_DOWN操作;
#test Round rules #ROUND_UP & ROUND_DOWN print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_UP)) #8.54 print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_UP)) #-8.54 print (Decimal('8.530').quantize(Decimal('0.01'), rounding=ROUND_UP)) #8.53 print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_DOWN)) #8.53 print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_DOWN)) #8.53 #ROUND_CEILING & ROUND_FLOOR print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_CEILING)) #8.54 print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_CEILING))#-8.53 print (Decimal('8.532').quantize(Decimal('0.01'), rounding=ROUND_FLOOR)) #8.53 print (Decimal('-8.532').quantize(Decimal('0.01'), rounding=ROUND_FLOOR)) #-8.54 #ROUND_HALF_ print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) #8.54 print (Decimal('8.534').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) #8.53 print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.53 print (Decimal('8.534').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.53 print (Decimal('8.536').quantize(Decimal('0.01'), rounding=ROUND_HALF_DOWN)) #8.54 print (Decimal('8.535').quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN)) #8.54 print (Decimal('8.545').quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN)) #8.54
decimal模塊先簡單了解到這里,還有許多函數(shù),后面如果用到,再查閱文檔。
到此這篇關(guān)于python中decimal模塊的用法的文章就介紹到這了,更多相關(guān)python decimal模塊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pytorch中transforms.Resize()的簡單使用
這篇文章主要介紹了Pytorch中transforms.Resize()的簡單使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Python運(yùn)行時(shí)修改業(yè)務(wù)SQL代碼
這篇文章主要介紹了Python運(yùn)行時(shí)修改業(yè)務(wù)SQL代碼,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06Python搭建HTTP服務(wù)器和FTP服務(wù)器
這篇文章主要為大家詳細(xì)介紹了Python搭建HTTP服務(wù)器和FTP服務(wù)器的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Python3 socket即時(shí)通訊腳本實(shí)現(xiàn)代碼實(shí)例(threading多線程)
這篇文章主要介紹了Python3 socket即時(shí)通訊腳本實(shí)現(xiàn)代碼實(shí)例(threading多線程),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06opencv調(diào)用yolov3模型深度學(xué)習(xí)目標(biāo)檢測實(shí)例詳解
這篇文章主要為大家介紹了opencv調(diào)用yolov3模型深度學(xué)習(xí)目標(biāo)檢測實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11