Binary to Decimal to Hexadecimal - How and Why
Tags: beginners, python
Published: 2021-09-18 22:40:28

## Why?

Computers store data as binary (base 2). Programmers like to read and write binary as hexadecimal (base 16). And humans use decimal (base 10). Therefore, as a human programmer who needs to talk to computers, you need to know a little bit about all three systems.

## Binary and Decimal

First, I'll walk you through how to convert between binary and decimal. Here's a table of each place in base 2 for one byte of data:

|  1  |  1  |  1  |  1  |  1  |  1  |  1  |  1  |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
| 128 |  64 |  32 |  16 |  8  |  4  |  2  |  1  |

### Binary to Decimal

To convert from binary to decimal by hand, simply write the powers of 2 beneath and add the numbers from right to left.

|  1  |  0  |  1  |  1  |  0  |  0  |  1  |  1  |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
| **128** |  ~~64~~ |  **32** |  **16** |  ~~8~~  |  ~~4~~  |  **2**  |  **1**  |

```
1 + 2 + 16 + 32 + 128 = 179
```

Let's say we have a binary string in Python code. How could we write a loop that will go through the string from right to left and add powers of 2?

```python
def bin_to_dec(bin_string):
    decimal = 0
    # Initialize our rightmost power of 2 (2^0)
    power_of_2 = pow(2, 0);
    # Iterate through the reversed binary string (R -> L)
    for b in bin_string[::-1]:
        # If the digit is 1
        if int(b) == 1:
            # Add the power of 2 to our decimal number
            decimal += power_of_2
        # Double the power of 2 for the next place
        power_of_2 *= 2
    # Output the result
    return decimal

# Prints 179
print(bin_to_dec("10110011")) 
```

### Decimal to Binary

There are multiple ways to convert from decimal to binary. I will teach you the way of dividing and taking the remainder. You divide by 2 and prepend the remainder to your binary string until the number you are dividing is 0.

```
179 / 2 = 89R1
_______1
 89 / 2 = 44R1
______11
 44 / 2 = 22R0
_____011
 22 / 2 = 11R0
____0011
 11 / 2 =  5R1
___10011
  5 / 2 =  2R1
__110011
  2 / 2 =  1R0
_0110011
  1 / 2 =  0R1
10110011
```

Here's the python code for that:

```python
def dec_to_bin(decimal):
    bin_string = ""
    power_of_2 = pow(2, 0)
    while decimal > 0:
        # The remainder of dividing by 2 is the next bin digit
        bin_digit = decimal % 2
        # Divide the decimal by two (floor division)
        decimal //= 2
        # Prepend digit to string w/string concatenation
        bin_string = str(bin_digit) + bin_string
        # Double the power of 2 for the next place
        power_of_2 *= 2
    # Output the result
    return bin_string

# Prints "10110111"
print(dec_to_bin(179))
```

### Generalizing: Base N to Decimal and Back

By the way, these approaches of converting bases works for any base system, including hexadecimal.

> The code below uses Python's [`ord()` and `chr()` functions](https://www.askpython.com/python/built-in-methods/python-chr-and-ord-methods) which are used to convert ASCII letters to numbers and back.

```python
def n_to_dec(n_string, n):
    decimal = 0
    power_of_n = pow(n, 0);
    for b in n_string[::-1]:
        # A = 10, B = 11, C = 12 ...
        b = ord(b) - 65 + 10 if not b.isdigit() else int(b)
        if int(b) != 0:
            decimal += int(b) * power_of_n
        power_of_n *= n
    return decimal

# Prints 255
print(n_to_dec("FF", 16))
```

```python
def dec_to_n(decimal, n):
    n_string = ""
    power_of_n = pow(n, 0)
    while decimal > 0:
        n_digit = decimal % n
        # 10 = A, 11 = B, 12 = C ...
        n_digit = chr(65 - 10 + n_digit) if n_digit >= 10 else n_digit
        decimal //= n
        n_string = str(n_digit) + n_string
        power_of_n *= n
    return n_string

# Prints FF
print(dec_to_n(255, 16))
```

## Hexadecimal and Binary

Sometimes, it is more useful to communicate in binary than decimal because you are talking about bytes of data. For example, a color's RGB values are each limited to a range of 0 to 255 because they each use a byte of data. However, writing out all of those 1's and 0's is tedious, so hexadecimal is used as a shorthand, where each nybble (half a byte, or 4 bits) is represented with a character from the set `0123456789ABCDEF`. For example:

```
0011 = 3
0110 = 6
1100 = C (12)
```

You can take any binary number and convert it to hexadecimal by taking each section of 4 bits right to left and converting those.

```
10100101 (bin)
```
|1010 |0101 |
|:---:|:---:|
|  A  |  5  |
```
A5 (hex)
```

## Conclusion

Of course, there are built in functions in languages like Python's `bin()` and `hex()` that will do these conversions, but it's useful to know how the process works yourself so you can do a quick conversion when needed. Now, the next time you see a color written as `#FFFFFF`, you will know that each RGB value is 255 and the lights are all on (making white). Hope you found this helpful!