Return to Blog

Numeric types in Python

By John Lekberg on August 29, 2020.


In this week's post, you will learn about Python's 6 different numeric types, and the numeric tower exposed by the numbers module.

Python's numeric types

Python has 4 built-in numeric types:

The standard library adds 2 more numeric types:

It's useful to have these different numeric types for different use cases. E.g. rounding error occurs when adding float objects, but not when adding Fraction objects:

.1 + .2 == .3
False
.1 + .2 
0.30000000000000004
from fractions import Fraction as F

F("0.1") + F("0.2") == F("0.3")
True
F("0.1") + F("0.2")
Fraction(3, 10)

But what happens when different numeric types interact?

So, what are the rules that control how different numeric types interact? In Python, these rules are known as the "numeric tower".

Python's numeric tower

Python's numeric tower is exposed by the numbers module. (See PEP 3141 for details.)

numbers exposes 5 abstract base classes:

  1. numbers.Number
  2. numbers.Complex
  3. numbers.Real
  4. numbers.Rational
  5. numbers.Integral

These classes form a hierarchy:

from numbers import Number, Complex, Real, Rational, Integral

issubclass(Complex, Number)
True
issubclass(Real, Complex)
True
issubclass(Rational, Real)
True
issubclass(Integral, Rational)
True

If you want to know how the numeric types fit into this hierarchy, it's most useful to pair each numeric type with the most specific class in the numeric tower:

Numeric towerNumeric types
NumberDecimal*
Complexcomplex
Realfloat
RationalFraction
Integralint, bool

* Although Decimal is "in" the numeric tower (it subclasses Number), it doesn't follow the implicit conversion rules used by the other numeric types. Decimal interacts with int:

from decimal import Decimal as D

D(3) + 4
Decimal('7')

But, Decimal does not interact with complex, float, or Fraction:

D(3) + complex(4)
TypeError: unsupported operand type(s) for +: 'decimal.Decimal'
  and 'complex'
D(3) + float(4)
TypeError: unsupported operand type(s) for +: 'decimal.Decimal'
  and 'float'
from fractions import Fraction as F

D(3) + F(4)
TypeError: unsupported operand type(s) for +: 'decimal.Decimal'
  and 'Fraction'

As a result, I don't consider Decimal to be a part of the numeric tower.


Making these pairings will allow us to better understand what happens when different numeric types interact.

What happens when different numeric types interact?

When two different numeric types interact, the type of the result is the more general type. E.g.

However, this can cause problems with float and complex objects, because of the limitations of their representation of the real ℝ (and complex ℂ) numbers:

In conclusion...

In this week's post, you learned about Python's 6 different numeric types, and the numeric tower exposed by the numbers module:

My challenge to you:

NumPy a popular 3rd-party library introduces more numeric types:

"Data type objects (dtype)"

Read about the different numeric types and compare them to Python's standard 6 types.

Ask yourself questions, like:

If you enjoyed this week's post, share it with your friends and stay tuned for next week's post. See you then!


(If you spot any errors or typos on this post, contact me via my contact page.)