Even the most basic mathematical operations can sometimes produce wrong results. This is due to the limitations in storing the exact values of certain numbers. You can overcome these limitations by using the decimal
module in Python. Similarly, neither the math
and cmath
modules we learned in the previous tutorial will help us perform fraction-based arithmetic operations. However, the fractions
module in Python happens to do just that.
This tutorial will introduce these two modules and the different functions they provide.
from decimal import Decimal Decimal(121) # 返回 Decimal('121') Decimal(0.05) # 返回 Decimal('0.05000000000000000277555756') Decimal('0.05') # 返回 Decimal('0.05') Decimal((0, (8, 3, 2, 4), -3)) # 返回 Decimal('8.324') Decimal((1, (8, 3, 2, 4), -1)) # 返回 Decimal('-832.4')
As you can see, the value of the getcontext()
function determines the accuracy of the calculation, rounding rules, and exception-raising behavior.
You can use the setcontext()
function to get and set the current context of the calculation. Use the with
statement to temporarily change the context of the calculation.
module that can be used for calculations: ROUND_HALF_UP
, ROUND_HALF_EVEN
and ROUND_HALF_EVEN
as their rounding algorithms. Another difference between these contexts is the exception-provoking behavior. DefaultContext
No exceptions related to numerical overflow, invalid operation, and division by zero are raised. BasicContext
enables almost all exceptions, which is great for debugging, while DefaultContext
is used as the default context for calculations.
The following is an example of how to use different contexts to get different results for simple division:
import decimal from decimal import ROUND_DOWN, ROUND_UP, Decimal as D dec_a = D('0.153') dec_b = D('0.231') zero = D('0') print("无上下文(使用默认值): ", dec_a/dec_b) # 无上下文(使用默认值): 0.6623376623376623376623376623 decimal.setcontext(decimal.BasicContext) print("基本上下文: ", dec_a/dec_b) # 基本上下文: 0.662337662 decimal.setcontext(decimal.ExtendedContext) print("扩展上下文: ", dec_a/dec_b) # 扩展上下文: 0.662337662 print("扩展上下文: ", dec_b/zero) # 扩展上下文: Infinity decimal.setcontext(decimal.DefaultContext) print("默认上下文: ", dec_a/dec_b) # 默认上下文: 0.6623376623376623376623376623 with decimal.localcontext() as l_ctx: l_ctx.prec = 5 l_ctx.rounding = ROUND_UP print("局部上下文: ", dec_a/dec_b) # 局部上下文: 0.66234
In addition to noting the differences in precision and rounding algorithms for different contexts, you may also observe that under ExtendedContext
, the division result for 0 is Infinity
.
decimal
Many functions in the
import decimal from decimal import Decimal as D print(D('22').sqrt(decimal.BasicContext)) # 4.69041576 print(D('22').sqrt(decimal.ExtendedContext)) # 4.69041576 print(D('22').sqrt(decimal.DefaultContext)) # 4.690415759823429554565630114 with decimal.localcontext() as l_ctx: l_ctx.prec = 5 print(D('22').sqrt(l_ctx)) # 4.6904
Using the Fractions modulefractions
Create scorefractions
The Fraction
decimal
module allows you to create
from fractions import Fraction from decimal import Decimal Fraction(11, 35) # 返回 Fraction(11, 35) Fraction(10, 18) # 返回 Fraction(5, 9) Fraction('8/25') # 返回 Fraction(8, 25) Fraction(1.13) # 返回 Fraction(1272266894732165, 1125899906842624) Fraction('1.13') # 返回 Fraction(113, 100) Fraction(Decimal('1.13')) # 返回 Fraction(113, 100)
Arithmetic operation of fractions
You can also perform simple mathematical operations on fractions like normal numbers, such as addition and subtraction.from decimal import Decimal Decimal(121) # 返回 Decimal('121') Decimal(0.05) # 返回 Decimal('0.05000000000000000277555756') Decimal('0.05') # 返回 Decimal('0.05') Decimal((0, (8, 3, 2, 4), -3)) # 返回 Decimal('8.324') Decimal((1, (8, 3, 2, 4), -1)) # 返回 Decimal('-832.4')
The module also has some important methods, such as limit_denominator(max_denominator)
, which will find and return a fraction closest to the value given fraction, with a denominator of at most max_denominator
. You can also use the numerator
attribute to return the numerator of a given fraction (denoted as the lowest term) and the denominator
attribute to return the denominator.
import decimal from decimal import ROUND_DOWN, ROUND_UP, Decimal as D dec_a = D('0.153') dec_b = D('0.231') zero = D('0') print("无上下文(使用默认值): ", dec_a/dec_b) # 无上下文(使用默认值): 0.6623376623376623376623376623 decimal.setcontext(decimal.BasicContext) print("基本上下文: ", dec_a/dec_b) # 基本上下文: 0.662337662 decimal.setcontext(decimal.ExtendedContext) print("扩展上下文: ", dec_a/dec_b) # 扩展上下文: 0.662337662 print("扩展上下文: ", dec_b/zero) # 扩展上下文: Infinity decimal.setcontext(decimal.DefaultContext) print("默认上下文: ", dec_a/dec_b) # 默认上下文: 0.6623376623376623376623376623 with decimal.localcontext() as l_ctx: l_ctx.prec = 5 l_ctx.rounding = ROUND_UP print("局部上下文: ", dec_a/dec_b) # 局部上下文: 0.66234
You can also use this module with various functions in the math
module to perform fraction-based calculations.
import decimal from decimal import Decimal as D print(D('22').sqrt(decimal.BasicContext)) # 4.69041576 print(D('22').sqrt(decimal.ExtendedContext)) # 4.69041576 print(D('22').sqrt(decimal.DefaultContext)) # 4.690415759823429554565630114 with decimal.localcontext() as l_ctx: l_ctx.prec = 5 print(D('22').sqrt(l_ctx)) # 4.6904
These two modules should be enough to help you perform common operations on decimal numbers and fractions. As shown in the last section, you can use these modules with the math
module to calculate the values of various mathematical functions in the format you wish.
In the next tutorial in this series, you will learn the random
module in Python.
The above is the detailed content of Mathematical Modules in Python: Decimal and Fractions. For more information, please follow other related articles on the PHP Chinese website!