[Python] Python+decimal完成精度计算的示例详解

1881 0
Honkers 2022-11-9 17:14:23 | 显示全部楼层 |阅读模式
目录

    1. 浮点数转Decimal2. Decimal除法设置3. Quantize设置结果4. Decimal精度设置

在进行小数计算的时候使用float,经常会出现小数位不精确的情况。在python编程中,推荐使用decimal来完成小数位的精度计算。
decimal是python中的标准库,直接将Decimal导入到代码块中使用。
decimal意思为十进制,这个模块提供了十进制浮点运算支持。通过几个常见的实战用例来说明一下其用法。

1. 浮点数转Decimal

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

#Itconvertsthefloat10.245toaDecimalobject.
decimal_=Decimal.from_float(10.245)

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

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

2. Decimal除法设置

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

#Itsetstheprecisionofthedecimalmoduleto8.
getcontext().prec=8

#Dividing1by6andstoringtheresultinthevariable`decimal_`.
decimal_=Decimal(1)/Decimal(6)

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

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

3. Quantize设置结果

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

#Roundingthenumber3.7829totwodecimalplaces.
decimal_=Decimal('3.7829').quantize(Decimal('0.00'))

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

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

4. Decimal精度设置

这里还是做一个结果为无限小数的除法,分别使用向上取整、向下取整的方式保留一定位数的小数来说明问题。
一般情况下可能使用的都是向上取整,但是在一些领域比较金融、证券行业就必须采取向下取整的方式,首先来看一下常用的向上取整的方式来保留小数。
#Itimportsallthenamesfromthedecimalmoduleintothecurrentnamespace.
fromdecimalimport*

#ItsetstheroundingmodetoROUND_CEILING.
getcontext().rounding=getattr(decimal,'ROUND_CEILING')

#Itsetstheprecisionofthedecimalmoduleto10.
getcontext().prec=10

#Convertingtheinteger9toastringandthenconvertingittoaDecimalobject.
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的属性为向下取整即可,为了对比结果我们还是采用同样的数据来看看效果。
#Itimportsallthenamesfromthedecimalmoduleintothecurrentnamespace.
fromdecimalimport*

#ItsetstheroundingmodetoROUND_CEILING.
getcontext().rounding=getattr(decimal,'ROUND_FLOOR')

#Itsetstheprecisionofthedecimalmoduleto10.
getcontext().prec=10

#Convertingtheinteger9toastringandthenconvertingittoaDecimalobject.
decimal_=Decimal(1)/Decimal(str(9))

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

#向下取整保留10位小数:0.1111111111
可以发现同样的数据做除法,向下取整时结果是0.1111111111,向上取整时结果是0.1111111112。
同样,还是很多的其他保留小数的方式可以使用比如四舍五入的方式,这也是很多很多行业会采取的一种小数保留的方式,再演示一下四舍五入时的保留小数。
#Itimportsallthenamesfromthedecimalmoduleintothecurrentnamespace.
fromdecimalimport*

#ItsetstheroundingmodetoROUND_HALF_UP.
getcontext().rounding=getattr(decimal,'ROUND_HALF_UP')

#Itsetstheprecisionofthedecimalmoduleto4.
getcontext().prec=5

#Itconvertsthestring'3.14159'toaDecimalobject.
decimal_=Decimal('3.14159')

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

#四舍五入保留4位小数:3.1416
将3.14159通过四舍五入的方式保留4位小数之后就变成了3.1416,和我们预想的结果一样。
到此这篇关于Python+decimal完成精度计算的示例详解的文章就介绍到这了,更多相关Python decimal精度计算内容请搜索中国红客联盟以前的文章或继续浏览下面的相关文章希望大家以后多多支持中国红客联盟!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4004
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行