如何在Python中使用十进制模块

451 阅读6分钟

本文将介绍Python中 "小数 "模块的使用指南。它可以用来对浮点数或含有小数点的数字进行各种数学运算。本文的所有代码样本都是在Ubuntu 21.04上用Python 3.9.5测试的。

关于小数模块

小数模块,顾名思义,可以用来处理有小数点的数字或浮动型数字。该模块中包含的方法有助于对小数点数字进行四舍五入,转换数字和进行算术计算。它还非常注重精确性和准确性,小数点后的每个数字都被认为是重要的。小数点模块认为1.40这样的数字是1.40,而不是1.4。小数点模块的使用可以通过实例得到最好的理解。下面将对其中的一些例子进行解释。

使用十进制模块进行基本的数学计算

你可以在Python中调用十进制构造函数来将一个数字转换为十进制类型。下面的代码示例显示了在整数类型的数字上进行的基本数学除法和小数类型的数字之间的区别。

from decimal import Decimal

a = 10
b = 11
c = a / b
d = Decimal(a) / Decimal(b)
print (c, type(c))
print (d, type(d))

第一条语句从十进制模块中导入十进制类。接下来,两个变量 "a "和 "b "被创建,带有一些值。变量 "c "存储了一个由变量a除以b产生的数值,然后重复同样的过程,将数字转换为十进制类型对象。运行上述代码示例后,你应该得到以下输出。

0.9090909090909091 <class 'float'>
0.9090909090909090909090909091 <class 'decimal.Decimal'>

正如你在上面的输出中看到的,float类型对象显示的数字比十进制类型对象的精度要低,因为它使用了比十进制类型对象更积极的近似方法。默认情况下,Python中的十进制类型数字最多显示28个数字。你可以通过调用十进制模块中的 "getcontext "方法根据你的需要改变这个值。

from decimal import Decimal
from decimal import getcontext

getcontext().prec = 50
a = 10
b = 11
c = a / b
d = Decimal(a) / Decimal(b)
print (c, type(c))
print (d, type(d))

在上面的代码示例中,getcontext函数已经被导入,并且精度位置已经被设置为最多50个位置。getcontext方法可以用来查看线程中的当前上下文,并改变小数模块的一些默认配置参数。运行上述代码示例后,你应该得到以下输出。

0.9090909090909091 <class 'float'>
0.90909090909090909090909090909090909090909090909091 <class 'decimal.Decimal'>

你可以用十进制类型的对象进行任何类型的算术计算,就像你在Python中用float类型的对象进行计算一样。十进制类型对象中大量的尾部小数可以带来精确的数字,在金融、会计、关键任务的科学应用等方面特别有用。

注意,你可以通过调用主Decimal构造函数,从浮点数、整数和包含数字的字符串中创建十进制类型的数字。

使用十进制模块对数字进行舍入

十进制模块带有一些预定义的四舍五入模式,你可以用这些模式来舍弃带有小数点的数字。这些模式被称为 ROUND_FLOOR, ROUND_CEILING, ROUND_HALF_DOWN, ROUND_HALF_UP, ROUND_UP, ROUND_DOWN, ROUND_HALF_EVEN, 和 ROUND_05UP。根据Python官方文档,下面是这些模式的各自作用。

  • ROUND_FLOOR: 数值被四舍五入到负无穷大。
  • ROUND_CEILING: 数字被四舍五入到无穷大或正无穷大。
  • ROUND_HALF_DOWN: 数字被四舍五入到最近的数字。如果有一个平局,数字被四舍五入到零。平局是指可以向上或向下舍入的等距数字。例如,像4.25这样的数字可以向4.2和4.3四舍五入。
  • ROUND_HALF_UP:数字被四舍五入到最近的数字。如果出现平局,则从零开始取整。
  • ROUND_UP: 数字从零开始四舍五入。
  • ROUND_DOWN: 数字被四舍五入到零。
  • ROUND_HALF_EVEN: 数字被四舍五入到最近的数字。任何并列的数字都被四舍五入为最接近的偶数整数。
  • ROUND_05UP: 如果最后一个数字是0或5,则从零开始取整。如果不是,那么数字将被四舍五入为零。

下面的代码示例显示了这些模式的行为。

import decimal
from decimal import Decimal
from decimal import getcontext

getcontext().prec = 2

getcontext().rounding = decimal.ROUND_FLOOR
print (Decimal(3.961) + Decimal(0))

getcontext().rounding = decimal.ROUND_CEILING
print (Decimal(3.961) + Decimal(0))

getcontext().rounding = decimal.ROUND_HALF_DOWN
print (Decimal(3.705) + Decimal(0))

getcontext().rounding = decimal.ROUND_HALF_UP
print (Decimal(3.775) + Decimal(0))

getcontext().rounding = decimal.ROUND_UP
print (Decimal(3.775) + Decimal(0))

getcontext().rounding = decimal.ROUND_DOWN
print (Decimal(3.609) + Decimal(0))

getcontext().rounding = decimal.ROUND_HALF_EVEN
print (Decimal(3.665) + Decimal(0))

getcontext().rounding = decimal.ROUND_05UP
print (Decimal(3.675) + Decimal(0))

这个代码示例非常直接。为四舍五入的数字设置了2位的精度。通过设置 "四舍五入 "对象(主上下文的一部分)的值来改变舍入方法。运行上述代码样本后,你应该得到以下输出,其中每一行都对应着各自的四舍五入模式。

3.9  
4.0  
3.7  
3.8  
3.8  
3.6  
3.7  
3.6

使用量化方法进行舍入

你也可以使用十进制模块中的 "量化 "方法对数字进行舍入。这个过程与上面解释的方法相同。然而,你可以提供一个指数作为量化方法的参数,将一个数字四舍五入到一个特定的位置,而不是单独设置精度的数字。下面是一个代码示例。

import decimal
from decimal import Decimal

rounded = Decimal(3.961).quantize(Decimal('1.0'), rounding=decimal.ROUND_FLOOR)
print (rounded)

指数'1.0'已被提供给quantize方法,四舍五入方法已被作为额外参数提供。它将返回一个X.X格式的数字。运行上述代码样本后,你应该得到以下输出。

3.9

比较两个十进制数字

你可以使用小数模块中的 "比较 "方法来比较任何两个小数类型的对象。下面的例子显示了它的用法。

from decimal import Decimal

print (Decimal(1.2).compare(Decimal(1.1)))
print (Decimal(1.0).compare(Decimal(1.1)))
print (Decimal(1.0).compare(Decimal(1.0)))

你可以在一个十进制类型的对象上调用比较方法,并提供另一个数字作为参数。根据被比较的数字,将返回一个0、1或-1的值。值为0表示两个数字相等,值为1表示第一个数字大于第二个数字,值为1表示第一个数字小于第二个数字。 运行上述代码样本后,你应该得到以下输出。

1  
-1  
0

结论

尽管小数点模块最常被用来控制小数点的精度和对小数点后的数字进行四舍五入,但它也有一些其他有用的方法,可以进一步用来操作小数点数字,以产生准确的算术计算结果。本文已经介绍了小数点模块的基本用法,对大多数情况来说应该是足够了。