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

作者:Sir 时间:2022-09-18 11:07:35 

在进行小数计算的时候使用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,和我们预想的结果一样。

来源:https://mp.weixin.qq.com/s/P1wapmw96-aFG1iULR9VlA

标签:Python,decimal,精度,计算
0
投稿

猜你喜欢

  • 通过vue提供的keep-alive减少对服务器的请求次数

    2024-05-28 16:10:40
  • Mozilla专有JavaScript扩展之一(__noSuchMethod__)

    2009-03-01 12:45:00
  • python os.path.isfile()因参数问题判断错误的解决

    2021-06-24 08:17:47
  • vue+element-ui+ajax实现一个表格的实例

    2024-04-10 10:34:27
  • 简述MySql四种事务隔离级别

    2024-01-18 12:52:11
  • 怎样生成utf-8编码的html文件

    2009-03-11 19:34:00
  • 解决Python中由于logging模块误用导致的内存泄露

    2021-08-24 08:04:46
  • Python实现K-means聚类算法并可视化生成动图步骤详解

    2021-06-20 23:10:40
  • Python实现CAN报文转换工具教程

    2022-06-13 02:34:06
  • 当设计师遇上前端开发

    2009-05-04 14:05:00
  • JS实现div居中示例

    2024-04-28 09:47:39
  • Python 3.x基础实战检查磁盘可用空间

    2021-05-11 09:21:25
  • Python实现栈的方法详解【基于数组和单链表两种方法】

    2022-06-05 19:03:47
  • Quasar Input:type="number" 去掉上下小箭头 实现加减按钮样式功能

    2024-04-16 09:13:02
  • Oracle不同数据库间对比分析脚本

    2024-01-17 07:05:07
  • python中的迭代和可迭代对象代码示例

    2023-02-17 21:13:24
  • SpringBoot用多线程批量导入数据库实现方法

    2024-01-23 23:03:36
  • Vue3通过ref操作Dom元素及hooks的使用方法

    2024-04-27 16:07:32
  • python已协程方式处理任务实现过程

    2022-05-10 03:12:56
  • Windows版Mysql5.6.11的安装与配置教程

    2024-01-24 18:24:48
  • asp之家 网络编程 m.aspxhome.com