python中的decimal类型转换实例详解
[Python标准库]decimal——定点数和浮点数的数学运算
       作用:使用定点数和浮点数的小数运算。
       Python版本:2.4及以后版本
       decimal模块实现了定点和浮点算术运算符,使用的是大多数人所熟悉的模型,而不是程序员熟悉的模型,即大多数计算机硬件实现的IEEE浮点数运算。Decimal实例可以准确地表示任何数,对其上取整或下取整,还可以对有效数字个数加以限制。
Decimal
        小数值表示为Decimal类的实例。构造函数取一个整数或字符串作为参数。使用浮点数创建Decimal之前,可以先将浮点数转换为一个字符串,使调用者能够显式地处理值得位数,倘若使用硬件浮点数表示则无法准确地表述。另外,利用类方法from_float()可以转换为精确的小数表示。 
importdecimal
fmt='{0:<25}{1:<25}'
printfmt.format('Input','Output')
printfmt.format('-'*25,'-'*25)
#Integer
printfmt.format(5,decimal.Decimal(5))
#String
printfmt.format('3.14',decimal.Decimal('3.14'))
#Float
f=0.1
printfmt.format(repr(f),decimal.Decimal(str(f)))
printfmt.format('%.23g'%f,str(decimal.Decimal.from_float(f))[:25])
       浮点数值0.1并不表示为一个精确的二进制值,所以float的表示与Decimal值不同。在这个输出中它被截断为25个字符。
       Decimal还可以由元组创建,其中包含一个符号标志(0表示正,1表示负)、数字tuple以及一个整数指数。 
importdecimal #Tuple t=(1,(1,1),-2) print'Input:',t print'Decimal:',decimal.Decimal(t)
       基于元组的表示创建时不太方便,不过它提供了一种可移植的方式,可以导出小数值而不会损失精度。tuple形式可以在网络上传输,或者在不支持精确小数值得数据库中存储,以后再转回回Decimal实例。
算术运算
Decimal重载了简单的算术运算符,所以可以采用内置数值类型同样的方式处理Decimal实例。
importdecimal
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:
printa+d
exceptTypeError,e:
printe
       Decimal运算符还接受整数参数,不过浮点数值必须转换为Decimal实例。
       除了基本算术运算,Decimal还包括一些方法来查找以10为底的对数和自然对数。log10()和ln()返回的值都是Decimal实例,所以可以与其他值一样直接在公式中使用。
特殊值
除了期望的数字值,Decimal还可以表示很多特殊值,包括正负无穷大值、“不是一个数”(NaN)和0。
importdecimal
forvaluein['Infinity','NaN','0']:
printdecimal.Decimal(value),decimal.Decimal('-'+value)
print
#Mathwithinfinity
print'Infinity+1:',(decimal.Decimal('Infinity')+1)
print'-Infinity+1:',(decimal.Decimal('-Infinity')+1)
#PrintcomparingNaN
printdecimal.Decimal('NaN')==decimal.Decimal('Infinity')
printdecimal.Decimal('NaN')!=decimal.Decimal(1)
       与无穷大值相加会返回另一个无穷大值。与NaN比较相等性总会返回false,而比较不等性总会返回true。与NaN比较大小来确定排序顺序没有明确定义,这会导致一个错误。
上下文
       到目前为止,前面的例子使用的都是decimal模块的默认行为。还可以使用一个上下文(context)覆盖某些设置,如保持精度、如何完成取整、错误处理等等。上下文可以应用于一个线程中的所有Decimal实例,或者局部应用于一个小代码区。     
1.当前上下文
要获取当前全局上下文,可以使用getcontext()。
importdecimal importpprint 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属性控制着作为算术运算结果所创建的新值的精度。字面量值会按这个属性保持精度。
importdecimal
d=decimal.Decimal('0.123456')
foriinrange(4):
decimal.getcontext().prec=i
printi,':',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取整。
importdecimal
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)
printheader_fmt.format('',
'1/8(1)','-1/8(1)',
'1/8(2)','-1/8(2)',
'1/8(3)','-1/8(3)',
)
forrounding_modeinROUNDING_MODES:
print'{0:10}'.format(rounding_mode.partition('_')[-1]),
forprecisionin[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.局部上下文
使用Python2.5或以后版本时,可以使用with语句对一个代码块应用上下文。
importdecimal
withdecimal.localcontext()asc:
c.prec=2
print'Localprecision:',c.prec
print'3.14/3=',(decimal.Decimal('3.14')/3)
print
print'Defaultprecision:',decimal.getcontext().prec
print'3.14/3=',(decimal.Decimal('3.14')/3)
Context支持with使用的上下文管理器API,所以这个设置只在块内应用。
5.各实例上下文
上下文还可以用来构造Decimal实例,然后可以从这个上下文继承精度和转换的取整参数。
importdecimal
#Setupacontextwithlimitedprecision
c=decimal.getcontext().copy()
c.prec=3
#Createourconstant
pi=c.create_decimal('3.1415')
#Theconstantvalueisroundedoff
print'PI:',pi
#Theresultofusingtheconstantusestheglobalcontext
print'RESULT:',decimal.Decimal('2.01')*pi
这样一来,应用就可以区别于用户数据精度而另外选择常量值精度。
6.线程
“全局”上下文实际上是线程本地上下文,所以完全可以使用不同的值分别配置各个线程。
importdecimal
importthreading
fromQueueimportPriorityQueue
classMultiplier(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)
defrun(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')
#APriorityQueuewillreturnvaluessortedbyprecision,nomatter
#whatorderthethreadsfinish.
q=PriorityQueue()
threads=[Multiplier(a,b,i,q)foriinrange(1,6)]
fortinthreads:
t.start()
fortinthreads:
t.join()
foriinrange(5):
prec,value=q.get()
printprec,'\t',value
这个例子使用指定的值创建一个新的上下文,然后安装到各个线程中。
总结
以上所述是小编给大家介绍的python中的decimal类型转换实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
