Python Base n Representation

Chapter 14 7 mins

Learning outcomes:

  1. Native binary, hexadecimal and octal notations
  2. Converting to bin, hex and oct formats
  3. Converting from bin, hex and oct to decimal

Introduction

The numbers we use in our everyday calculations are based on the decimal number system, also known as the denary number system.

In this system, the number 10 is used as the base. Each digit in a denary number placeholds a power of 10. For example, starting from the right side and going leftwards, the first digit represents 100 = 1; the second digit represents 101 = 10, the third one represent 100; and so on.

Computers, as we know, follow another number system. They work in binary numbers, where each digit can either be a 0 or a 1. This time, each digit is a power of 2 — this is the base of binary numbers.

Now binary numbers can get long and gibberish very quickly. The binary representation of 35000 is 1000100010111000.

See how cryptic the binary equivalent of 35000 looks! This is the reason why we humans can't work the same way with binary numbers as computers can — we just can't comprehend the never-ending sequences of 0s and 1s!

This is where hexadecimal and octal numbers step in. As can be judged by the names, hexadecimal uses base 16 while octal uses base 8.

Numbers that otherwise span long lines in binary notation, span considerably lesser space in hex and oct notations.

In this chapter, we shall explore the conversion of numbers in Python across these four bases. Specifically, we'll see how to go from bin, hex and oct notation to decimal numbers, and then how to use strings to represent bin, hex and oct numbers.

Representing numbers in binary, octal and hexadecimal

To represent an integer, specifically in decimal representation, we don't need to do anything special — just write the integer, as it is.

x = 10 # 10 in decimal notation

However, to represent a number in binary, hexadecimal or octal notation, we need to use a prefix.

For binary the prefix is 0b; for hexadecimal, it's 0x; and for octal it's 0o.

We put a prefix, so that Python knows exactly how to convert the number into a decimal equivalent.

All prefixes start with a 0 and end with an alphabet, which can be lowercase or uppercase. For instance, both the prefixes 0b and 0B are the same. However, owing to the fact that in uppercase, 0O (octal prefix) might look like two zeroes, it's preferred to use lowercase alphabets.

The 'b' in 0b comes from 'binary'; the 'x' in 0x comes from 'hexadecimal'; and the 'o' in 0o comes from octal.

A number written in this way gets converted from the respective base into a decimal integer by Python.

Let's see some examples in all three of these notations:

x = 15

bin_x = 0b1111
hex_x = 0xf
oct_x = 017
bin_x
15
hex_x
15
oct_x
15

In line 3, 0b1111 represents the binary number 1111 which is 15 in decimal, and gets converted into this decimal equivalent. If we print bin_x we see that it is 15.

Moving on, 0xf represents the hexadecimal number f, which is also 15 in decimal, and ultimately gets converted into this decimal number.

The number 0o17 denotes the octal number 17 which is once again, equal to 15.

Converting to bin, hex and oct

In the section above, we saw how to go from bin, hex and oct representations to the decimal representation by prefixing the numbers with the respective prefix and then letting the interpreter do its computation.

It's also possible to go from decimal to these 3 representations. However you have to understand one key idea here..

Non-decimal numbers are stringified

Numbers in Python are based on the decimal number system. Any number in any other notation is automatically converted into a decimal number, as we saw above.

This means that if you wish to get the representation of a decimal number in binary, hexadecimal or octal notation, you will get it in the format of a string.

A number that is represented within a string, is known as a stringified number.

With this in mind, let's now see the ways to convert numbers from decimal notation to binary, hexadecimal and octal representations.

The bin(), hex() and oct() functions take a single argument which is an integer, and return its representation in their corresponding number system.

The return value of each of these functions is a string, that is preceded by the respective number system's prefix — 0b for binary, 0x for hexadecimal and 0o for octal.

The snippet below illustrates a couple of conversions:

bin(20)
'0b10100'
hex(17)
'0x11'
oct(30)
'0o36'

Converting from string to decimal

Let's say you've converted a number from decimal notation to binary using the bin() function, or have a similar case with the hex() or oct() functions. What you have in the end is a string representing the number.

Now what if you wish to go back from this string to the original decimal integer? This isn't something one wouldn't ever want to do!

Fortunately, Python has a way — use the int() function with its second parameter.

The int() function can be used to convert a stringified number into an integer in Python.

The second parameter to the int() function specifies the base of the number that is provided as the first argument. It ought to be an integer. The default value is 10, which is the base of the decimal number system.

In this way, the interpreter knows how to translate the stringified number (in the first arg) into decimal representation.

For example to convert the stringified binary number '1111' (or equivalently '0b1111') into an integer, we would call int('1111', 2). The second arg is 2 since 1111 is a binary number and we know that binary numbers have a base of 2.

Similarly, to convert 'fa' from hexadecimal to decimal, we'll call int('fa', 16) this time passing 16 as the second arg. This is because hexadecimal numbers have a base of 16.

The stringified number passed to int() as the first argument can also contain a prefix. For example, calling int('1111', 2) is the same as calling int('0b1111', 2).
The second argument to int() must be an integer!

How to convert the stringified number '645' from octal representation to decimal representation?

  • int('645', '0o')
  • int('645', '8')
  • int('645', 8)