The int type in Python: whole numbers

The int type covers Python's whole numbers: no decimal point, no size limit, and built from a string with int().
5 min read
Believemy logo

Definition

Counting things calls for a number type that refuses any decimal point. The attempts a user has left, the age typed into a form, the position of an item in a list: none of these numbers make sense with a decimal attached. Python answers that need with int, the type of whole numbers, the ones with no decimal point and no remainder, whether positive, negative or zero.

It is also the default type. Write a number with no dot in your code, and Python turns it into an int on its own, no annotation required. And unlike most languages, its size is bounded by nothing other than the memory available on the machine: no ceiling fixed in advance, no silent overflow that would send a counter back into negative values.

PYTHON
age = 34
balance = -120
counter = 0

print(type(age))
# <class 'int'>

The name int covers both the type and the function that builds a value of it, which often surprises beginners: writing int("42") changes nothing in place, it builds a fresh whole number from reading the string, and leaves the original variable untouched.


Building one from a string

Everything entering a program enters as text. The input function always hands back a string, never a number. A form field does the same, and so does a column read from a CSV file. Converting that string into an int becomes a move made almost without thinking, any time a calculation has to follow a piece of user input.

PYTHON
entry = input("Your age: ")
age = int(entry)

if age >= 18:
    print("Adult")

Skipping that step does not forgive itself. Comparing text against a number makes Python raise a TypeError, and when the string handed over does not represent a valid whole number, building one fails with a ValueError. That second error can be caught with a try/except block, which makes it possible to politely ask for input again instead of letting the program stop dead.

The table below sums up what int() accepts and refuses, because the boundary is not always where it seems.

ExpressionResult
int("42")42
int(" 42 ")42, surrounding spaces are ignored
int("42.5")ValueError, the decimal point is refused
int(42.9)42, the decimal part is cut off
int(True)1, a bool already is a whole number
Warning

Converting a decimal number to a whole number truncates towards zero, never rounds: int(-2.9) gives -2 and not -3, a difference that quietly throws off a total whenever a rounded value was expected. To round to the nearest value, call round before converting.


The divisions are not equal

Dividing two whole numbers with / often surprises beginners: the result is never a whole number, even when the calculation comes out even. 10 / 2 gives 5.0, decimal point included, because Python wants to keep room for a remainder rather than ever making it disappear silently. To stay within whole numbers, two other operators exist: // returns the quotient, % returns the remainder.

PYTHON
10 / 3   # 3.3333333333333335
10 // 3  # 3
10 % 3   # 1

pages = (total + 9) // 10

That pair settles most real needs: spreading items across pages, telling whether a number is even by testing its remainder against 2, turning seconds into minutes. One situation stays off limits no matter the form the division takes: dividing by zero, which always raises a ZeroDivisionError.


A size with no ceiling

In many languages, a whole number eventually overflows: past a certain value, the counter wraps back to zero or flips into negative territory, with no warning. Python avoids that trap by setting no fixed limit on its whole numbers, just one single family that keeps growing for as long as the machine's memory allows.

PYTHON
print(2 ** 200)
# 1606938044258990275541962092341162602522202993782792835301376

That freedom comes at a cost: calculations on genuinely huge numbers run slower. But in exchange it removes a whole family of bugs that are hard to reproduce, the kind that only show up months into use, once a counter has finally overflowed somewhere else.

Good to know

A whole number literal can contain underscores to stay readable, without changing its value: 1_000_000 equals exactly 1000000. Python simply ignores them while reading the code.

Whole numbers hold one more advantage over decimal numbers: they stay exact, addition after addition, where a float piles up small rounding errors invisible to the eye. That is why a rule is widely followed in code that handles money: store amounts in cents, as whole numbers, and convert them to a currency display only when the time comes to show them.


Frequently asked questions

Question

How can a value be confirmed as a whole number?

The type function displays it directly, and isinstance(value, int) checks it inside a condition. One detail worth knowing: a boolean answers true to that test, since Python treats it as a whole number worth 0 or 1.

Question

Why does int() refuse the entry "3.5"?

Because building a whole number only accepts digits, possibly preceded by a sign, never a decimal point. Text that holds one must go through float first, then through a conversion to a whole number if truncating the result is genuinely wanted.

Question

Does the type have to be declared before assigning a number to a variable?

No, Python always works it out from the value written, and the same variable can hold text a few lines later with nothing standing in the way. Type annotations document the intent for analysis tools, but they are never checked while the program runs.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.