Python中小数数字

Python2.4开始引入一种新的核心数据类型:小数对象。 比其他数据类型复杂一些,小数是通过通过一个导入的模块调用函数后创建,而不是通过运行常量表示式来创建。从功能上来说,小数对象就像浮点数,只不过它们有固定的位数和小数点,因此小数是有固定的精度的浮点数。

使用了小数对象,我们能够使用一个只保留两位小数位精度的浮点数。此外,我们能够定义如何省略和截断额外的小数数字。尽管它对平常的浮点数类型来说带来了微小的性能损失,小数类型对表现固定精度的特性(例如,钱的总和)以及对实现更好的数字精度是一个理想的工具。

一个困惑的问题:

>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17

>>> print(0.1 + 0.1 + 0.1 - 0.3)
5.551115123125783e-17
>>>

上面的计算结果或打印本应该得到0,结果却是一个接近0的数字,我们都知道,这是因为与硬件相关的浮点数运算在精度方面的内在的缺陷! 如果在数字要求很严格的地方,比如银行显然是不允许的。上述问题,如果使用小数对象,是可以解决的

>>> from decimal import Decimal
>>> Decimal("0.1") + Decimal("0.1") + Decimal("0.1") - Decimal("0.3")
Decimal('0.0')

>>>

Decimal函数还可以随着输入的小数位数,自动升级位数:

>>> Decimal("0.1") + Decimal("0.10") + Decimal("0.10") - Decimal("0.30")
Decimal('0.00')

>>>

设置全局精度:

decimal模块中的其他工具还可以用来设置所有小数数值的精度、设置错误处理等。 例如,这个模块中的一个上下文对象允许对象指定精度和舍入模式。 该精度全局性地适用于调用线程中创建的所有小数:

>>> from decimal import Decimal              # 未设置精度
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')

>>> decimal.getcontext().prec = 2            # 设置精度为2
>>> Decimal(1) / Decimal(7)
Decimal('0.14')

>>>

这对于处理货币的应用程序特别有用,其中,美分表示为两个小数位数。这个上下文里,小数实际上是手动舍入和字符串格式化的一种替代方式:

>>> 1999 + 1.33
2000.33

>>> decimal.getcontext().prec = 2
>>> pay = decimal.Decimal(str(1999 + 1.33))
>>> pay
Decimal('2000.33')

>>>

小数上下文管理器

Python 2.6及之后的版本,可使用上下文管理器语句来重新设置临时精度。和前面比较起来,优点在于:在语句退出后,精度又重新设置为初始值。

>>> import decimal
>>> decimal.Decimal("1.00") / decimal.Decimal("3.00")
Decimal('0.33333333')

>>> with decimal.localcontext() as ctx:                  # 上下文管理器
...     ctx.prec = 2
...     decimal.Decimal("1.00") / decimal.Decimal("3.00")
Decimal('0.33')

>>> decimal.Decimal("1.00") / decimal.Decimal("3.00")    # 设置完不影响后面设置
Decimal('0.33333333')

>>>

 

你可能感兴趣的:(【编程语言】)