# Numbering systems¶

The basic example of how numbering systems work:

Base 10:

53 = 5*10 + 3

192 = 1*100 + 9*10 + 2

693914 = 6*$10^5$ + 9*$10^4$ + 3*$10^3$ + 9*$10^2$ + 1*$10^1$ + 4*$10^0$

Or

693014 = 6*$\mathbf{10}^5$ + 9*$\mathbf{10}^4$ + 3*$\mathbf{10}^3$ + 0*$\mathbf{10}^2$ + 1*$\mathbf{10}^1$ + 4*$\mathbf{10}^0$

This "10" means that we are currently using decimal numbers, or base 10.

Changing this number means changing the base.

## Examples of non-decimal numbers (conversion to base 10)¶

### Base 6:¶

53 = 5*6 + 3 (which is 33 in base 10)

100 = 1*36 + 0*6 + 0 (which is 36 in base 10)

192 = ??? (there is no number 9 in base 6, there are only numbers 0, 1, 2, 3, 4, 5)

23240400 = 2*$6^7$ + 3*$6^6$ + 2*$6^5$ + 4*$6^4$ + 0*$6^3$ + 4*$6^2$ + 0*$6^1$ + 0*$6^0$ (which is 720720 in base 10)

### Base 2:¶

1010 = 1*8 + 0*4 + 1*2 + 0*1 (which is 10 in base 10)

110111 = 1*32 + 1*16 + 0*8 + 1*4 + 1*2 + 1*1 (which is 55 in base 10)

### Base 16:¶

For any base there number of available digits equals the base. So, only two digits (0 and 1) for base 2, 10 digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) for base 10.

Therefore, extra symbols for "10, 11, 12, 13, 14 and 15" are needed for base 16. Latin letters A, B, C, D, E and F are used as these digits.

10AB = 1*16^3 + 0*16^2 + A*16^1 + B*16^0

Converting to base 10:

1*$16^3$ + 0*$16^2$ + A*$16^1$ + B*$16^0$ =
1*4096 + 0*256 + A*16 + B*1 = 4096 + 10*16 + 11 = 4267

So, 10AB in base 16 is 4267 in base 10.

### In general:¶

To convert a number from some other base to base 10, you represent the number as a mathematical expression. For a number "xyzzy" in some base b the expression is

x*$b^4$ + y*$b^3$ + z*$b^2$ + z*$b^1$ + y*$b^0$

Then you perform multiplications, take the sum are get the number in base 10.

In [ ]:
original_number = '2324'
original_base = 6

# dec_number =

# there is a default python way of converting any base to decimal:
number = int(original_number, original_base)
print(number)
# Do not use it here

556
556


## Example problems¶

Convert the following numbers to base 10:

100, 244, 121 from base 6,
10101101 from base 2,

## Conversion from base 10¶

To convert numbers to base 10 you use multiplication and compute the sum. To convert numbers from base 10 to other bases you use division.

For example, converting the number 53 to base 6 will look like this:

53 // 6 = 8 (+5 as a remainder)
8 // 6 = 1 (+2 as a remainder)
1 is less than 6

The answer is 125. We can check if it's the correct answer:

125(6) = 1*36 + 2*6 + 5 = 36 + 12 + 5 = 53(10)

### Base 2¶

Converting the same number 53 to binary:

53 // 2 = 26 (+1 as a remainder)
26 // 2 = 13 (+0 as a remainder)
13 // 2 = 6 (+1 as a remainder)
6 // 2 = 3 (+0 as a remainder)
3 // 1 = 1 (+1 as a remainder)
1 is less than 2

The result is 110101.

### Base 16¶

The last example, converting 4267 back to base 16.

4267 // 16 = 266 (+11 as a remainder)
266 // 16 = 16 (+10 as a remainder)
16 // 16 = 1 (+0 as a remainder)
1 is less than 16

The answer is 1 0 10 11. Or 10AB.

In [ ]:
original_number = 1000
to_base = 8

# use this line:

# result should be a string

print (number)

1750
1000


## Example problems¶

Convert the following numbers from base 10 to bases 2, 6 and 16:

153, 200, 25.

## Numbering systems based on powers of 2¶

Computers store all information in binary, so you have to understand how binary works if you want to better understand the low-level processes in computers.

Binary is inconvenient in some respects. Particularly, even small numbers are represented as long strings in binary.

110111(2) is 55(10)
10101101100111(2) is 11111(10)

Luckily, it is quite easy to convert binary to base 16 and back.

Base 2:    11  0111
Base 10:    3    7
Base 16:    3    7

And

Base 2:   10 1011 0110 0111
Base 10:   2   11    6    7
Base 16:   2    B    6    7

2 binary digits always convert to a single hexadecimal digit, so you can do the conversion by groups of 4 digits.

Bytes of computer information are groups of 8 binary digits, and they can be represented as two hexadecimal digits.

Octal numbering system is also used in some cases. An octal digit can represent 3 binary digits.

Base 2:   10 101 101 100 111
Base 8:    2   5   5   4   7

This way you can easily convert numbers between binary and any other "power of two" base.

An example of converting backwards:

Base 16:    9    5    A    5    A
Base 10:    9    5   10    5   10
Base 2:  1001 0101 1010 0101 1010

Base 10 is used just to illustrate the base 16 digits, this method doesn't help with conversion to base 10.

## Example problems¶

Convert FF5733 to binary and then to octal.

Convert 10715526 (8) from octal to binary and then to base 16.

# Arithmetic in non-decimal bases¶

Earlier there were mostly examples of conversion between decimal and other bases. There wasn't any reason for this other than base 10 being the default base for us and the base we are used to. It's possible to move all arithmetic and all math to other bases.

You can add up numbers just like in base 10. You add up digits, then, if the result is larger or equal to the base, you carry 1 to the next digit.

   111  1
010010101101 +
100011100100
============
110110010001

The first row marks places where 1 is carried in the sum.

Now base 6:

1 11
2352 +
4144
====
10540

## Multiplication¶

Just like for base 10, you need a multiplication table for all 1-digit numbers so it is easier to perform multiplication.

For binary the table is quite simple:

   | 0 | 1 |
0 | 0   0 |
1 | 0   1 |

For base 6 it's more complex:

   | 0 | 1 | 2 | 3 | 4 | 5 |
0 | 0   0   0   0   0   0 |
1 | 0   1   2   3   4   5 |
2 | 0   2   4  10  12  14 |
3 | 0   3  10  13  20  23 |
4 | 0   4  12  20  24  32 |
5 | 0   5  14  23  32  41 |

Using such a table for a particular base, you can multiply numbers of this base just like decimals.

   1101 *
110
=======
0
1101   +
1101
=======
1001110

Try multiplying 1011 by 1001 in binary.

One of the applications where binary directly comes into play is network routing.

IP address is an important part of the network structure. Usually it is written as 4 decimal numbers separated by dots:

208.80.154.224 - an IP address used by Wikimedia Foundation.

Sometimes several IP addresses are united in a subnetwork, where they have a fixed prefix and differ only by the last several binary digits.

These masks can be written as "/25" or 255.255.255.128. In this example, both these masks mean that the first 25 binary digits of an IP address stay the same and the last 8 ones change.

Address: 11010000.01010000.10011010.11100000
Network: 11010000.01010000.10011010.10000000

By applying the mask to the address (that is, using an "AND" operation, or multiplying each digit of an address to a digit of a mask) you get a network prefix.

111.49.45.105
39.134.166.136
203.213.41.232

# Writing a converter¶

Python has a default way of converting numbers from other bases to base 10 as a part of the function int. However, if you want to convert numbers to other bases, you have to implement the algorithm yourself.

In [ ]:
alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
original_number = '255'

from_base = 10
to_base = 16
result = ''

# convert the number to base 10
number = int(original_number, from_base)