[Python標準庫]decimal――定點數和浮點數的數學運算
??????? 作用:使用定點數和浮點數的小數運算。
??????? Python 版本:2.4 及以后版本
??????? decimal 模塊實現了定點和浮點算術運算符,使用的是大多數人所熟悉的模型,而不是程序員熟悉的模型,即大多數計算機硬件實現的 IEEE 浮點數運算。Decimal 實例可以準確地表示任何數,對其上取整或下取整,還可以對有效數字個數加以限制。
Decimal
???????? 小數值表示為 Decimal 類的實例。構造函數取一個整數或字符串作為參數。使用浮點數創建 Decimal 之前,可以先將浮點數轉換為一個字符串,使調用者能夠顯式地處理值得位數,倘若使用硬件浮點數表示則無法準確地表述。另外,利用類方法
from_float()
可以轉換為精確的小數表示。?
import decimal
fmt = '{0:<25} {1:<25}'
print fmt.format('Input', 'Output')
print fmt.format('-' * 25, '-' * 25)
# Integer
print fmt.format(5, decimal.Decimal(5))
# String
print fmt.format('3.14', decimal.Decimal('3.14'))
# Float
f = 0.1
print fmt.format(repr(f), decimal.Decimal(str(f)))
print fmt.format('%.23g' % f, str(decimal.Decimal.from_float(f))[:25])
??????? 浮點數值 0.1 并不表示為一個精確的二進制值,所以 float 的表示與 Decimal 值不同。在這個輸出中它被截斷為 25 個字符。
??????? Decimal 還可以由元組創建,其中包含一個符號標志(0 表示正,1 表示負)、數字 tuple 以及一個整數指數。?
import decimal
# Tuple
t = (1, (1, 1), -2)
print 'Input :', t
print 'Decimal:', decimal.Decimal(t)
??????? 基于元組的表示創建時不太方便,不過它提供了一種可移植的方式,可以導出小數值而不會損失精度。tuple 形式可以在網絡上傳輸,或者在不支持精確小數值得數據庫中存儲,以后再轉回回 Decimal 實例。
算術運算
??????? Decimal 重載了簡單的算術運算符,所以可以采用內置數值類型同樣的方式處理 Decimal 實例。
import decimal
a = decimal.Decimal('5.1')
b = decimal.Decimal('3.14')
c = 4
d = 3.14
print 'a =', repr(a)
print 'b =', repr(b)
print 'c =', repr(c)
print 'd =', repr(d)
print
print 'a + b =', a + b
print 'a - b =', a - b
print 'a * b =', a * b
print 'a / b =', a / b
print
print 'a + c =', a + c
print 'a - c =', a - c
print 'a * c =', a * c
print 'a / c =', a / c
print
print 'a + d =',
try:
print a + d
except TypeError, e:
print e
??????? Decimal 運算符還接受整數參數,不過浮點數值必須轉換為 Decimal 實例。
??????? 除了基本算術運算,Decimal 還包括一些方法來查找以 10 為底的對數和自然對數。log10() 和 ln() 返回的值都是 Decimal 實例,所以可以與其他值一樣直接在公式中使用。
特殊值??
????? 除了期望的數字值,Decimal 還可以表示很多特殊值,包括正負無窮大值、“不是一個數”(NaN)和 0。
import decimal
for value in [ 'Infinity', 'NaN', '0' ]:
print decimal.Decimal(value), decimal.Decimal('-' + value)
print
# Math with infinity
print 'Infinity + 1:', (decimal.Decimal('Infinity') + 1)
print '-Infinity + 1:', (decimal.Decimal('-Infinity') + 1)
# Print comparing NaN
print decimal.Decimal('NaN') == decimal.Decimal('Infinity')
print decimal.Decimal('NaN') != decimal.Decimal(1)
??????? 與無窮大值相加會返回另一個無窮大值。與 NaN 比較相等性總會返回 false,而比較不等性總會返回 true。與 NaN 比較大小來確定排序順序沒有明確定義,這會導致一個錯誤。
上下文
??????? 到目前為止,前面的例子使用的都是 decimal 模塊的默認行為。還可以使用一個上下文(context)覆蓋某些設置,如保持精度、如何完成取整、錯誤處理等等。上下文可以應用于一個線程中的所有 Decimal 實例,或者局部應用于一個小代碼區。?????
?1. 當前上下文
??????? 要獲取當前全局上下文,可以使用 getcontext()。
import decimal
import pprint
context = decimal.getcontext()
print 'Emax =', context.Emax
print 'Emin =', context.Emin
print 'capitals =', context.capitals
print 'prec =', context.prec
print 'rounding =', context.rounding
print 'flags ='
pprint.pprint(context.flags)
print 'traps ='
pprint.pprint(context.traps)
??????? 這個示例腳本顯示了 Context 的公共屬性。
?? ????? 2. 精度
??????? 上下文的 prec 屬性控制著作為算術運算結果所創建的新值的精度。字面量值會按這個屬性保持精度。
import decimal
d = decimal.Decimal('0.123456')
for i in range(4):
decimal.getcontext().prec = i
print i, ':', d, d * 1
??????? 要改變精度,可以直接為這個屬性賦一個新值。
?? ????? 3. 取整
??????? 取整有多種選擇,以保證值在所需精度范圍內。
?ROUND_CEILING 總是趨向于無窮大向上取整。
?ROUND_DOWN 總是趨向 0 取整。
?ROUND_FLOOR 總是趨向負無窮大向下取整。
?ROUND_HALF_DOWN 如果最后一個有效數字大于或等于 5 則朝 0 反方向取整;否則,趨向 0 取整。
?ROUND_HALF_EVEN 類似于 ROUND_HALF_DOWN,不過,如果最后一個有效數字值為 5,則會檢查前一位。偶數值會導致結果向下取整,奇數值導致結果向上取整。
?ROUND_HALF_UP 類似于 ROUND_HALF_DOWN,不過如果最后一位有效數字為 5,值會朝 0 的反方向取整。
?ROUND_UP 朝 0 的反方向取整。
?ROUND_05UP 如果最后一位是 0 或 5,則朝 0 的反方向取整;否則向 0 取整。
import decimal
context = decimal.getcontext()
ROUNDING_MODES = [
'ROUND_CEILING',
'ROUND_DOWN',
'ROUND_FLOOR',
'ROUND_HALF_DOWN',
'ROUND_HALF_EVEN',
'ROUND_HALF_UP',
'ROUND_UP',
'ROUND_05UP',
]
header_fmt = '{:10} ' + ' '.join(['{:^8}'] * 6)
print header_fmt.format(' ',
'1/8 (1)', '-1/8 (1)',
'1/8 (2)', '-1/8 (2)',
'1/8 (3)', '-1/8 (3)',
)
for rounding_mode in ROUNDING_MODES:
print '{0:10}'.format(rounding_mode.partition('_')[-1]),
for precision in [ 1, 2, 3 ]:
context.prec = precision
context.rounding = getattr(decimal, rounding_mode)
value = decimal.Decimal(1) / decimal.Decimal(8)
print '{0:^8}'.format(value),
value = decimal.Decimal(-1) / decimal.Decimal(8)
print '{0:^8}'.format(value),
print
?這個程序顯示了使用不同算法將同一個值取整為不同精度的效果。
??????? 4. 局部上下文
??????? 使用 Python 2.5 或以后版本時,可以使用 with 語句對一個代碼塊應用上下文。
import decimal
with decimal.localcontext() as c:
c.prec = 2
print 'Local precision:', c.prec
print '3.14 / 3 =', (decimal.Decimal('3.14') / 3)
print
print 'Default precision:', decimal.getcontext().prec
print '3.14 / 3 =', (decimal.Decimal('3.14') / 3)
????? Context 支持 with 使用的上下文管理器 API,所以這個設置只在塊內應用。
??? ???? 5. 各實例上下文
??????? 上下文還可以用來構造 Decimal 實例,然后可以從這個上下文繼承精度和轉換的取整參數。
import decimal
# Set up a context with limited precision
c = decimal.getcontext().copy()
c.prec = 3
# Create our constant
pi = c.create_decimal('3.1415')
# The constant value is rounded off
print 'PI :', pi
# The result of using the constant uses the global context
print 'RESULT:', decimal.Decimal('2.01') * pi
??????? 這樣一來,應用就可以區別于用戶數據精度而另外選擇常量值精度。
?????? ? 6. 線程
??????? “全局”上下文實際上是線程本地上下文,所以完全可以使用不同的值分別配置各個線程。
import decimal
import threading
from Queue import PriorityQueue
class Multiplier(threading.Thread):
def __init__(self, a, b, prec, q):
self.a = a
self.b = b
self.prec = prec
self.q = q
threading.Thread.__init__(self)
def run(self):
c = decimal.getcontext().copy()
c.prec = self.prec
decimal.setcontext(c)
self.q.put( (self.prec, a * b) )
return
a = decimal.Decimal('3.14')
b = decimal.Decimal('1.234')
# A PriorityQueue will return values sorted by precision, no matter
# what order the threads finish.
q = PriorityQueue()
threads = [ Multiplier(a, b, i, q) for i in range(1, 6) ]
for t in threads:
t.start()
for t in threads:
t.join()
for i in range(5):
prec, value = q.get()
print prec, '\t', value
這個例子使用指定的值創建一個新的上下文,然后安裝到各個線程中。
總結
以上所述是小編給大家介紹的python中的decimal類型轉換實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

