The numeric tower
We've seen Python's three built-in numeric types: int
, float
, complex
, plus two more types—Fraction
and Decimal
—imported from the standard library. The numbers module in the standard library provides four base class definitions for the numeric types. We rarely need to use this module explicitly; it's a convention that we need when we have to implement our own numeric types.
The numeric types form a kind of "tower" that parallels the various kinds of numbers seen in conventional mathematics. The foundation of the tower is integers. Rational numbers are above integers. Floating-point values are still further up, and complex numbers are at the top of the tower.
A common expectation is that a language will automatically coerce numeric values to permit expressions such as 2*2.718
to work properly and produce a useful result. When multiplying an integer by a float value, we expect integers to be coerced to a floating-point value.
In order for this to work, there are two general rules applied to the result of a binary arithmetic operation:
- If both operands are of the same type, the result has that type. For example,
2 ** 1024
does not produce a floating-point result. It produces an immense integer. - If the operands are mixed, one of them will be coerced "up" the numeric tower from integer → rational → floating-point → complex.
There is one notable exception to the preceding rules. The /
and //
operators define two different kinds of pision. The /
operator provides true pision: even integer operands will yield a floating-point result. For example:
>>> 355/113 3.1415929203539825
The //
operator provides floor pision: the result will be truncated as if it were an integer-only pision. The resulting type won't be coerced, but the answer will be truncated. For example:
>>> 355./113. 3.1415929203539825 >>> 355.//113. 3.0
The presence of the //
operator means that an expression which is designed with integers in mind will also work correctly with floating-point values. Similarly, we may write an expression with an informal expectation of floating-point values; by using /
, it will also work with integers.
Note that these coercion rules for numeric types do not apply to strings or other objects. Strings are not implicitly converted to numbers. The expression '2'+2
results in a TypeError
exception. We'll look at explicit conversions later, in the Using the built-in conversion functions section.
The tower metaphor provides a handy way to remember the coercion rules. Given two values from different levels, the lower-level value is coerced up the tower to the higher-level values.