Applying Math with Python
上QQ阅读APP看书,第一时间看更新

Python numerical types

Python provides basic numerical types such as arbitrarily sized integers and floating-point numbers (double precision) as standard, but it also provides several additional types that are useful in specific applications where precision is especially important. Python also provides (built-in) support for complex numbers, which are useful for some more advanced mathematical applications.

Decimal type

For applications that require decimal digits with accurate arithmetic operations, use theDecimal type from thedecimal module in the Python Standard Library:

from decimal import Decimal
num1 = Decimal('1.1')
num2 = Decimal('1.563')
num1 + num2 # Decimal('2.663')

Performing this calculation with float objects gives the result 2.6630000000000003, which includes a small error arising from the fact that certain numbers cannot be represented exactly using a finite sum of powers of 2. For example, 0.1 has a binary expansion 0.000110011..., which does not terminate. Any floating-point representation of this number will therefore carry a small error. Note that the argument to Decimal is given as a string rather than a float.

The Decimal type is based on the IBM General Decimal Arithmetic Specification (http://speleotrove.com/decimal/decarith.html), which is an alternative specification for floating-point arithmetic that represents decimal numbers exactly by using powers of 10 rather than powers of 2. This means that it can be safely used for calculations in finance where the accumulation of rounding errors would have dire consequences. However, the Decimal format is less memory efficient, since it must store decimal digits rather than binary digits (bits), and are more computationally expensive than traditional floating-point numbers.

Thedecimal package also provides aContext object, which allows fine-grained control over the precision, display, and attributes ofDecimal objects. The current (default) context can be accessed using thegetcontext function from the decimal module. TheContext object returned bygetcontext has a number of attributes that can be modified. For example, we can set the precision for arithmetic operations:

from decimal import getcontext
ctx = getcontext()
num = Decimal('1.1')
num**4 # Decimal('1.4641')
ctx.prec = 4 # set new precision
num**4 # Decimal('1.464')

When we set the precision to 4, rather than the default 28, we see that the fourth power of 1.1 is rounded to 4 significant figures.

The context can even be set locally by using thelocalcontextfunction, which returns a context manager that restores the original environment at the end of the with block:

from decimal import localcontext
num = Decimal("1.1")
with localcontext() as ctx:
ctx.prec = 2
num**4 # Decimal('1.5')
num**4 # Decimal('1.4641')

This means that the context can be freely modified inside the with block, and will be returned to the default at the end.

Fraction type

Alternatively, for working with applications that require accurate representations of integer fractions, such as when working with proportions or probabilities, there is the Fraction type from the fractions module in the Python Standard Library. The usage is similar, except that we typically give the numerator and denominator of the fraction as arguments:

from fractions import Fraction
num1 = Fraction(1, 3)
num2 = Fraction(1, 7)
num1 * num2 # Fraction(1, 21)

The Fraction type simply stores two integers, the numerator and the denominator, and arithmetic is performed using the basic rules for the addition and multiplication of fractions.

Complex type

Python also has support for complex numbers, including a literal character to denote the complex unit 1j in code. This might be different from the idiom for representing the complex unit that you are familiar with from other sources on complex numbers. Most mathematical texts will often use the symbol i to represent the complex unit:

z = 1 + 1j
z + 2 # 3 + 1j
z.conjugate() # 1 - 1j

Special "complex number" - aware mathematical functions are provided in the cmath module of the Python Standard Library.