亲宝软件园·资讯

展开

Python decimal精度计算

Sir 老王 人气:0

在进行小数计算的时候使用float,经常会出现小数位不精确的情况。在python编程中,推荐使用decimal来完成小数位的精度计算。

decimal是python中的标准库,直接将Decimal导入到代码块中使用。

decimal意思为十进制,这个模块提供了十进制浮点运算支持。通过几个常见的实战用例来说明一下其用法。

1. 浮点数转Decimal

使用Decimal.from_float函数将随便一个float类型的小数转换成Decimal的数据类型,结果float类型数据就显出原形了。

# It imports the Decimal class from the decimal module.
import decimal
from decimal import Decimal

# It converts the float 10.245 to a Decimal object.
decimal_ = Decimal.from_float(10.245)

print('浮点数转为Decimal后:{0}'.format(decimal_))

# 浮点数转为Decimal后:10.2449999999999992184029906638897955417633056640625

从结果来看,float浮点数转换完成以后精度位数就变得很长不是原先的三位小数了,这是因为float浮点数本身就不精确转换之后才会出现上面的效果。

2. Decimal除法设置

随机选两个整数将其定义为Decimal类型的数据,之后对这两个整个做除法通过保留相应的结果位数对其返回结果进行优化。

# It imports all the names from the decimal module into the current namespace.
from decimal import *

# It sets the precision of the decimal module to 8.
getcontext().prec = 8

# Dividing 1 by 6 and storing the result in the variable `decimal_`.
decimal_ = Decimal(1)/Decimal(6)

print('精确到8位小数后的结果是:{0}'.format(decimal_))

# 精确到8位小数后的结果是:0.16666667

很明显做除法以后的结果应该是一个无限小数,设置保留8位小数之后自动进行了四舍五入的计算得到0.16666667的结果。

3. Quantize设置结果

同样是保留了两位小数,使用quantize函数能完成同样的效果,默认结果也是经过了四舍五入的计算,若是想要固定小数位数使用此方法比较靠谱。

# It imports all the names from the decimal module into the current namespace.
from decimal import *

# Rounding the number 3.7829 to two decimal places.
decimal_ = Decimal('3.7829').quantize(Decimal('0.00'))

print('quantize设置保留两位小数后的结果:{0}'.format(decimal_))

# quantize设置保留两位小数后的结果:3.78

4. Decimal精度设置

这里还是做一个结果为无限小数的除法,分别使用向上取整、向下取整的方式保留一定位数的小数来说明问题。

一般情况下可能使用的都是向上取整,但是在一些领域比较金融、证券行业就必须采取向下取整的方式,首先来看一下常用的向上取整的方式来保留小数。

# It imports all the names from the decimal module into the current namespace.
from decimal import *

# It sets the rounding mode to ROUND_CEILING.
getcontext().rounding = getattr(decimal, 'ROUND_CEILING')

# It sets the precision of the decimal module to 10.
getcontext().prec = 10

# Converting the integer 9 to a string and then converting it to a Decimal object.
decimal_ = Decimal(1) / Decimal(str(9))

print('向上取整保留10位小数:{0}'.format(decimal_.quantize(Decimal('0.0000000000'))))

# 向上取整保留10位小数:0.1111111112

这里有个问题就是,如果getcontext().prec已经设置小数位是10,那么在使用quantize函数固定小数位的时候就必须不超过10位才行,也就是不能超过有效位数否则就会报错。

接下来看一下向下取整,向下取整的小数保留方式只需要修改getcontext().rounding的属性为向下取整即可,为了对比结果我们还是采用同样的数据来看看效果。

# It imports all the names from the decimal module into the current namespace.
from decimal import *

# It sets the rounding mode to ROUND_CEILING.
getcontext().rounding = getattr(decimal, 'ROUND_FLOOR')

# It sets the precision of the decimal module to 10.
getcontext().prec = 10

# Converting the integer 9 to a string and then converting it to a Decimal object.
decimal_ = Decimal(1) / Decimal(str(9))

print('向下取整保留10位小数:{0}'.format(decimal_.quantize(Decimal('0.0000000000'))))

# 向下取整保留10位小数:0.1111111111

可以发现同样的数据做除法,向下取整时结果是0.1111111111,向上取整时结果是0.1111111112。

同样,还是很多的其他保留小数的方式可以使用比如四舍五入的方式,这也是很多很多行业会采取的一种小数保留的方式,再演示一下四舍五入时的保留小数。

# It imports all the names from the decimal module into the current namespace.
from decimal import *

# It sets the rounding mode to ROUND_HALF_UP.
getcontext().rounding = getattr(decimal, 'ROUND_HALF_UP')

# It sets the precision of the decimal module to 4.
getcontext().prec = 5

# It converts the string '3.14159' to a Decimal object.
decimal_ = Decimal('3.14159')

print('四舍五入保留4位小数:{0}'.format(decimal_.quantize(Decimal('0.0000'))))

# 四舍五入保留4位小数:3.1416

将3.14159通过四舍五入的方式保留4位小数之后就变成了3.1416,和我们预想的结果一样。

加载全部内容

相关教程
猜你喜欢
用户评论