即使是最基本的数学运算,有时也会给出错误的结果。 发生这种情况是由于存储某些数字的确切值的限制。 您可以通过在Python中使用十进制模块来克服这些限制。 同样,在上一教程中学习的数学和cmath模块都不能帮助我们进行基于分数的算术运算。 但是,Python中的分数模块可以做到这一点。
在本教程中,您将了解这些模块以及它们提供的不同功能。
为什么我们需要一个十进制模块?
您可能想知道为什么当我们已经可以使用浮点数进行运算时,为什么需要使用十进制数进行基本算术的模块。
在回答这个问题之前,如果您在Python控制台中键入0.1 + 0.2
,我希望您对输出值进行一个猜测。 如果您猜测输出应该为0.3,那么当您查看实际结果0.30000000000000004时,您会感到惊讶。 您可以尝试其他计算,例如0.05 + 0.1
,您将得到0.15000000000000002。
要了解这里发生的情况,请尝试以十进制形式表示1/3
,您会注意到该数字实际上以10为基数不终止。类似地,某些数字(例如0.1或1/10)以2为基数也未终止。由于仍然需要以某种方式表示这些数字,因此在存储它们时会进行一些近似处理,从而导致这些错误。
这个数字0.30000000000000004实际上非常接近0.3,因此我们大多数时候都可以避免这种近似。 不幸的是,当您模拟卫星发射或处理金钱时,这种近似并不能削减它。 这些近似值的另一个问题是误差会不断堆积。
为了获得精确的结果,例如我们手工进行计算时要处理的结果,我们需要支持快速,正确舍入的十进制浮点算术的东西,而十进制模块正是这样做的。
使用十进制模块
在使用模块之前,您需要先将其导入。 之后,您可以根据整数,字符串,浮点数或元组创建小数。 当小数由整数或浮点数构成时,该数字的值将进行精确转换。 看下面的例子,看看我的意思:
from decimal import Decimal
Decimal(121)
# returns Decimal('121')
Decimal(0.05)
# returns Decimal('0.05000000000000000277555756')
Decimal('0.05')
# returns Decimal('0.05')
Decimal((0, (8, 3, 2, 4), -3))
# returns Decimal('8.324')
Decimal((1, (8, 3, 2, 4), -1))
# returns Decimal('-832.4')
如您所见, Decimal(0.05)
的值与Decimal('0.05')
略有不同。 这意味着当您添加0.05和0.1时,应使用decimal.Decimal('0.05')
和decimal.Decimal('0.1')
来构造小数。
from decimal import Decimal
Decimal('0.05') + Decimal('0.1')
# returns Decimal('0.15')
Decimal(0.05) + Decimal(0.1)
# returns Decimal('0.1500000000000000083266726847')
现在您可以对小数执行各种操作,您可能希望控制这些操作的精度或舍入。 这可以通过使用getcontext()
函数来完成。 除其他功能外,此功能还允许您获取并设置精度和舍入选项的值。
请记住,舍入和精度仅在算术运算中起作用,而在您自己创建小数位数时则没有作用。
import decimal
from decimal import Decimal, getcontext
Decimal(1) / Decimal(13)
# returns Decimal('0.07692307692307692307692307692')
getcontext().prec = 10
Decimal(0.03)
# returns Decimal('0.02999999999999999888977697537')
Decimal(1) / Decimal(7)
# returns Decimal('0.1428571429')
getcontext().rounding = decimal.ROUND_DOWN
Decimal(1) / Decimal(7)
# returns Decimal('0.1428571428')
您还可以将一些数学函数(例如sqrt()
, exp()
和log()
与小数一起使用。 这里有一些例子:
import decimal
from decimal import Decimal, getcontext
Decimal(2).sqrt()
# returns Decimal('1.414213562373095048801688724')
getcontext().prec = 4
Decimal('2').sqrt()
# returns Decimal('1.414')
Decimal('2000').log10()
# returns Decimal('3.301')
使用分数模块
有时,您可能会遇到需要对分数执行各种运算或最终结果需要是分数的情况。 在这些情况下,分数模块可以提供很大的帮助。 它允许您从数字,浮点数,小数甚至字符串创建Fraction
实例。 就像小数模块一样,从浮点数创建分数时,该模块也存在一些问题。 这里有一些例子:
from fractions import Fraction
from decimal import Decimal
Fraction(11, 35)
# returns Fraction(11, 35)
Fraction(10, 18)
# returns Fraction(5, 9)
Fraction('8/25')
# returns Fraction(8, 25)
Fraction(1.13)
# returns Fraction(1272266894732165, 1125899906842624)
Fraction('1.13')
# returns Fraction(113, 100)
Fraction(Decimal('1.13'))
# returns Fraction(113, 100)
您还可以像普通数字一样对分数执行简单的数学运算,例如对分数进行加减。
from fractions import Fraction
Fraction(113, 100) + Fraction(25, 18)
# returns Fraction(2267, 900)
Fraction(18, 5) / Fraction(18, 10)
# returns Fraction(2, 1)
Fraction(18, 5) * Fraction(16, 19)
# returns Fraction(288, 95)
Fraction(18, 5) * Fraction(15, 36)
# returns Fraction(3, 2)
Fraction(12, 5) ** Fraction(12, 10)
# returns 2.8592589556010197
该模块还具有一些重要的方法,例如limit_denominator(max_denominator)
,该方法将查找并返回其分母最多为max_denominator
的给定分数的最接近分数的分数。 您还可以通过使用numerator
属性返回最低分数中给定分数的numerator
,而使用denominator
属性返回denominator
。
from fractions import Fraction
Fraction('3.14159265358979323846')
# returns Fraction(157079632679489661923, 50000000000000000000)
Fraction('3.14159265358979323846').limit_denominator(10000)
# returns Fraction(355, 113)
Fraction('3.14159265358979323846').limit_denominator(100)
# returns Fraction(311, 99)
Fraction('3.14159265358979323846').limit_denominator(10)
# returns Fraction(22, 7)
Fraction(125, 50).numerator
# returns 5
Fraction(125, 50).denominator
# returns 2
您还可以将此模块与math模块中的各种功能一起使用,以执行基于分数的计算。
import math
from fractions import Fraction
math.sqrt(Fraction(25, 4))
# returns 2.5
math.sqrt(Fraction(28,3))
# returns 3.0550504633038935
math.floor(Fraction(3558, 1213))
# returns 2
Fraction(math.sin(math.pi/3))
# returns Fraction(3900231685776981, 4503599627370496)
Fraction(math.sin(math.pi/3)).limit_denominator(10)
# returns Fraction(6, 7)
最后的想法
这两个模块应足以帮助您对小数和小数执行通用操作。 如上一节中所示,您可以将这些模块与math模块一起使用,以所需的格式计算各种数学函数的值。
在本系列的下一个教程中,您将学习Python中的random模块。
翻译自: https://code.tutsplus.com/tutorials/mathematical-modules-in-python-decimal-and-fractions--cms-27691