4.1. Numbers#

Computers are designed to perform numerical calculations, but there are some important details about working with numbers that every programmer working with quantitative data should know. Python (like most other programming languages) distinguishes between two different types of numbers:

  • Integers are called int values in the Python language. They can only represent whole numbers (negative, zero, or positive) that don’t have a fractional component

  • Real numbers are called float values (or floating point values) in the Python language. They can represent whole or fractional numbers but have some limitations.

The type of a number is evident from the way it is displayed: int values have no decimal point and float values always have a decimal point.

# Some int values
2
2
1 + 3
4
-1234567890000000000
-1234567890000000000
# Some float values
1.2
1.2
3.0
3.0

When a float value is combined with an int value using some arithmetic operator, then the result is always a float value. In most cases, two integers combine to form another integer, but any number (int or float) divided by another will be a float value. Very large or very small float values are displayed using scientific notation.

1.5 + 2
3.5
3 / 1
3.0
-12345678900000000000.0
-1.23456789e+19

The type function can be used to find the type of any number.

type(3)
int
type(3 / 1)
float

The type of an expression is the type of its final value. So, the type function will never indicate that the type of an expression is a name, because names are always evaluated to their assigned values.

x = 3
type(x) # The type of x is an int, not a name
int
type(x + 2.5)
float

4.1.1. More About Float Values#

Float values are very flexible, but they do have limits.

  1. A float can represent extremely large and extremely small numbers. There are limits, but you will rarely encounter them.

  2. A float only represents 15 or 16 significant digits for any number; the remaining precision is lost. This limited precision is enough for the vast majority of applications.

  3. After combining float values with arithmetic, the last few digits may be incorrect. Small rounding errors are often confusing when first encountered.

The first limit can be observed in two ways. If the result of a computation is a very large number, then it is represented as infinite. If the result is a very small number, then it is represented as zero.

2e306 * 10
2e+307
2e306 * 100
inf
2e-322 / 10
2e-323
2e-322 / 100
0.0

The second limit can be observed by an expression that involves numbers with more than 15 significant digits. These extra digits are discarded before any arithmetic is carried out.

0.6666666666666666 - 0.6666666666666666123456789
0.0

The third limit can be observed when taking the difference between two expressions that should be equivalent. For example, the expression 2 ** 0.5 computes the square root of 2, but squaring this value does not exactly recover 2.

2 ** 0.5
1.4142135623730951
(2 ** 0.5) * (2 ** 0.5)
2.0000000000000004
(2 ** 0.5) * (2 ** 0.5) - 2
4.440892098500626e-16

The final result above is 0.0000000000000004440892098500626, a number that is very close to zero. The correct answer to this arithmetic expression is 0, but a small error in the final significant digit appears very different in scientific notation. This behavior appears in almost all programming languages because it is the result of the standard way that arithmetic is carried out on computers.

Although float values are not always exact, they are certainly reliable and work the same way across all different kinds of computers and programming languages.