一、decimal模块简介
decimal 意思为十进制,这个模块提供了十进制浮点运算支持。decimal模块的实例可以准确地表示任何数,对其上或其下取整,还可以限制有效数字个数。
二、decimal模块用法
1、Decimal() 的参数
(1)Decimal() 的参数:可以是整型或者字符串参数,但不能是浮点数据,因为浮点数据本身就不准确。
(2)实例:
from decimal import Decimal
print(Decimal(10))
print(Decimal("1.1"))
print(Decimal(1.1))
-------------------------------------------
10
1.1
1.100000000000000088817841970012523233890533447265625
2、浮点型数据转换
(1)浮点型数据转换:Decimal().from_float() 方法实现。
(2)实例:
from decimal import Decimal
print(Decimal(1.1))
print(Decimal().from_float(1.1))
-------------------------------------------
1.100000000000000088817841970012523233890533447265625
1.100000000000000088817841970012523233890533447265625
3、Decimal 类型数据转换为字符串
(1)Decimal 类型数据转换为字符串:使用 str() 方法即可。
(2)实现:
from decimal import Decimal
print(str(Decimal("1.123")))
-------------------------------------------
1.123
4、用元组的形式创建小数
(1)元组解析:(0,(1,2,3),-2)
- 元组参数一:0 表示正数;1 表示负数。
- 元组参数二:十进制整数,例如下面是198
- 元组参数三:小数点几位
(2)实例:
import decimal
t = (0,(1,2,3),-2)
d = decimal.Decimal(t)
print("元组解析后的小数:",d)
-------------------------------------------
元组解析后的小数:1.23
5、设置有效数字位数
(1)设置有效数字:使用 decimal.getcontext().prec 设置有效数字位数。
(2)实例:
from decimal import Decimal,getcontext
getcontext().prec = 4
d = Decimal("10")/Decimal("3")
print("设置4位有效数字:",d)
-------------------------------------------
设置4位有效数字:3.333
6、设置小数位数
(1)设置小数位数:使用 Decimal() 的 quantize 设置小数位数。
(2)实例:
from decimal import Decimal
d = Decimal(1.123456).quantize(Deciaml("0.000"))
print("保留3位小数:",d)
-------------------------------------------
保留3位小数:1.123
7、decimal 的取整
(1)取整:
- ROUND_CEILING :总是趋向无穷大向上取整。
- ROUND_FLOOR :总是趋向负无穷大向下取整。
- ROUND_DOWN :总是趋向 0 取整。
- ROUND_UP:朝 0 的反方向取整。
- ROUND_05UP:如果最后一位是 0 或 5,则朝0的反方向取整;否则向0取整。
- ROUND_HALF_DOWN :如果最后一个有效数字大于或等于 5 则朝 0 反方向取整;否则,趋向 0 取整。
- ROUND_HALF_EVEN :类似于ROUND_HALF_DOWN,不过,如果最后一个有效数字值为5,则会检查前一位,偶数值会导致结果向下取整,奇数值导致结果向上取整。
- ROUND_HALF_UP :类似于ROUND_HALF_DOWN,不过如果最后一位有效数字为 5,值会朝 0 的反方向取整。
(2)实例:
# 向上取整
import decimal
from decimal import Decimal,getcontext
getcontext().rounding = getattr(decimal,'ROUND_CEILING')
c = Decimal(10)/Decimal(3)
print(c.quantize(Decimal("0.0000")))
d = Decimal(10)/Decimal(6)
print(d.quantize(Decimal("0.0000")))
-------------------------------------------
3.3334
1.6667
-------------------------------------------
# 向下取整
import decimal
from decimal import Decimal,getcontext
getcontext().rounding = getattr(decimal,'ROUND_FLOOR')
c = Decimal(10)/Decimal(3)
print(c.quantize(Decimal("0.0000")))
d = Decimal(10)/Decimal(6)
print(d.quantize(Decimal("0.0000")))
-------------------------------------------
3.3333
1.6666
8、decimal 的算术运算
(1)decimal 算术运算:Decimal() 对象支持相互的算术运算,支持与 int 类型数值进行算术运算,但不支持与 float 类型数据进行算术运算。
(2)实例:
from decimal import Decimal
a = Decimal("6.28")
b = Decimal("3.14")
c = 2
d = 3.14
print(a,b,c,d)
print(a+b,a-b,a/b,a*b)
print(a+c,a-c,a/c,a*c)
try:
print(a+d)
except TypeError as e:
print("a+d=",e)
-------------------------------------------
6.28 3.14 2 3.14
9.42 3.14 2 19.7192
8.28 4.28 3.14 12.56
a+d= unsupported operand type(s) for +: 'decimal.Decimal' and 'float'
9、decimal 的特殊数值
(1)decimal 的特殊数值:包括正负无穷大、NaN,即 Infinity、NaN。
(2)实例:
from decimal import Decimal
print("正无穷大:",Decimal('Infinity')+1)
print("负无穷大:",Decimal('-Infinity')-1)
print("NaN和无穷大是否相等:",Decimal('NaN')==Decimal('Infinity'))
-------------------------------------------
正无穷大: Infinity
负无穷大: -Infinity
NaN和无穷大是否相等: False
10、decimal 的上下文属性获取
(1)decimal 的上下文属性:指 deciaml.getcontext 对象下的属性。
(2)实例:
from decimal import Decimal,getcontext
print("获取Emax属性:",getcontext().Emax)
print("获取Emin属性:",getcontext().Emin)
print("获取capitals属性:",getcontext().capitals)
# prec属性:用于设置 decimal 的有效位数
print("获取prec属性:",getcontext().prec)
# prec属性:用于设置 decimal 的取整方式
print("获取rounding属性:",getcontext().rounding)
-------------------------------------------
获取Emax属性: 999999
获取Emin属性: -999999
获取capitals属性: 1
获取prec属性: 28
获取rounding属性: ROUND_HALF_EVEN
11、decimal 的本地上下文
(1)decimal 的本地上下文:用于单独的运算,不要改变默认上下文的配置。
(2)实例:
from decimal import localcontext,getcontext,Decimal
with localcontext() as c:
c.prec = 2
print("localcontext precision: ",c.prec)
print("3.14/3 = ",Decimal("3.14")/3)
print("default precision: ",getcontext().prec)
print("3.14/3 = ",Decimal("3.14")/3)
-------------------------------------------
localcontext precision: 2
3.14/3 = 1.0
default precision: 28
3.14/3 = 1.046666666666666666666666667
12、decimal 的对数函数
(1)decimal 的对数函数:log10()、ln()
(2)实例:
from decimal import Decimal
print("log10(10) = ",Decimal(10).log10())
print("ln(10) = ",Decimal(10).ln())
-------------------------------------------
log10(10) = 1
ln(10) = 2.302585092994045684017991455
三、decimal模块应用实战
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, self.a * self.b))
a = decimal.Decimal('3.14')
b = decimal.Decimal('1.234')
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('{} {}'.format(prec, value))
decimal_thread_context.py
1 4
2 3.9
3 3.87
4 3.875
5 3.8748