python数字处理技巧(1): 精度舍入、精确运算、格式化、进制数、大数打包解包、复数、NaN、分数
1. 數(shù)字的四舍五入
當(dāng)我們需要對整數(shù) 或者 浮點數(shù)進行四舍五入的時候。
- round(value, ndigits) ?/// 內(nèi)置函數(shù)
對浮點數(shù)進行四舍五入(傳入的ndigit應(yīng)該是正值,作用于十分位、百分位...):
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(2.5, 0) ) #2.0 近似到最近的偶數(shù)對整數(shù)進行四舍五入(傳入的ndigit應(yīng)該是自然數(shù),作用于個位、十位、百位...)
print( round(314159, -1)) #314160 print( round(314159, -2)) #314200 print( round(314159, -3)) #314000Comment:
不要將舍入round和格式化format輸出搞混淆了。 如果我們目的只是簡單的輸出一定寬度的數(shù),不需要使用 round() 函數(shù)。 而僅僅只需要在格式化的時候指定精度即可。
pi = 3.1415926 print( format(pi, '0.2f')) #3.14 print( format(pi, '0.3f')) #3.142 print( 'the value is {:0.4f}'.format(pi) ) #the value is 3.14162. 執(zhí)行精確的浮點數(shù)運算
有的時候我們需要對浮點數(shù)進行精度運算,并不希望出現(xiàn)小的誤差。但是由于浮點數(shù)并不能精確的表示十進制數(shù)。 并且,即使是最簡單的數(shù)學(xué)運算也會產(chǎn)生小的誤差,比如:
a = 4.2 b = 2.1 print( a + b ) # 6.300000000000001 print( a+b == 6.3 ) #False這些錯誤是由底層CPU和IEEE 754標(biāo)準(zhǔn)通過自己的浮點單位去執(zhí)行算術(shù)時的特征。 由于Python的浮點數(shù)據(jù)類型使用底層表示存儲數(shù)據(jù),因此沒辦法去避免這樣的誤差。
- decimal模塊 ?耗時但是精確
如果想更加精確(并能容忍一定的性能損耗),我們可以使用?decimal 模塊:
from decimal import Decimala = Decimal('4.2') b = Decimal('2.1') print(a+b) # 6.3其實呢,這段代碼看起來好像有點奇怪,比如用字符串來表示數(shù)字。 然而,Decimal對象會像普通浮點數(shù)一樣的工作。 我們打印它們時,看起來卻跟普通數(shù)字沒什么兩樣。
decimal 模塊的一個主要特征是允許控制計算的每一方面,包括數(shù)字位數(shù)和四舍五入運算。 為了這樣做,我們需要創(chuàng)建一個本地上下文并更改它的設(shè)置。
from decimal import localcontexta = Decimal('1.3') b = Decimal('1.7') print(a / b) # 0.7647058823529411764705882353with localcontext() as ctx:ctx.prec = 3print(a / b) # 0.765with localcontext() as ctx:ctx.prec = 50print(a / b) #0.764705882352941176470588235294117647058823529411763. 數(shù)字的格式化輸出
需要將數(shù)字格式化后輸出,并控制數(shù)字的位數(shù)、對齊、千位分隔符和其他的細節(jié)。格式化輸出單個數(shù)字的時候,可以使用內(nèi)置的 format() 函數(shù),比如:
x = 1234.56789print(format(x, '0.2f')) #'1234.57' print(format(x, '>10.1f')) #' 1234.6' print(format(x, '<10.10f')) #'1234.5678900000' print(format(x, '^10.1f')) #' 1234.6 ' print(format(x, ',')) #1,234.56789 print(format(x, 'e')) #1.234568e+03 print('The value is {:0,.2f}'.format(x)) # The value is 1,234.574. 二八十六進制整數(shù)
為了將整數(shù)轉(zhuǎn)換為二進制、八進制或十六進制的文本串, 可以分別使用 bin() , oct() 或 hex()函數(shù)。
x = 1234 print( bin(x) ) # 0b10011010010 print( oct(x) ) # 0o2322 print( hex(x) ) # 0x4d2# 如果不想輸出0b,0o或者0x的,使用 format() 函數(shù) print( format(x, 'b') ) # 10011010010 print( format(x, 'o') ) # 2322 print( format(x, 'x') ) # 4d25. 字節(jié)到大整數(shù)的打包和解包
這里涉及到的是:如何將大整數(shù)利用字節(jié)進行處理。
- int.from_bytes() & int.to_bytes()
大整數(shù)和字節(jié)字符串之間的轉(zhuǎn)換操作并不常見。 然而,在一些應(yīng)用領(lǐng)域有時候也會出現(xiàn),比如密碼學(xué)或者網(wǎng)絡(luò)。 例如,IPv6網(wǎng)絡(luò)地址使用一個128位的整數(shù)表示。 如果要從一個數(shù)據(jù)記錄中提取這樣的值的時候。
6. 復(fù)數(shù)的數(shù)學(xué)運算
- complex(real, imag) 或者是帶有后綴j的浮點數(shù)來指定
7. 無窮大與NaN
Python并沒有特殊的語法來表示這些特殊的浮點值,但是可以使用 float() 來創(chuàng)建它們。
import math print( float('inf') ) # inf print( float('-inf') ) # -inf print( float('nan') ) # nana = float('inf') print( math.isinf(a) ) # true# 無窮大數(shù)在執(zhí)行數(shù)學(xué)計算的時候會傳播 print( a+45 ) # inf8. 分數(shù)運算
- fractions
fractions 模塊可以被用來執(zhí)行包含分數(shù)的數(shù)學(xué)運算。
from fractions import Fractiona = Fraction(5, 4) print( a ) # 5/4 print( a.numerator, a.denominator) # 5 4 print( float(a) ) # 1.25在大多數(shù)程序中一般不會出現(xiàn)分數(shù)的計算問題,但是有時候還是需要用到的。 比如,在一個允許接受分數(shù)形式的測試單位并以分數(shù)形式執(zhí)行運算的程序中, 直接使用分數(shù)可以減少手動轉(zhuǎn)換為小數(shù)或浮點數(shù)的工作。
總結(jié)
以上是生活随笔為你收集整理的python数字处理技巧(1): 精度舍入、精确运算、格式化、进制数、大数打包解包、复数、NaN、分数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: API 层实现语音录制
- 下一篇: 给程序员的忠告:九种不值得你追随的老板