# Hexadecimal

Hexadecimal (also just *hex*) is a base-16 numeral system, very commonly used in programming (alongside binary and octal). It more or less works exactly the same as our traditional base 10 numeral system, but in addition to digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 also includes digits *A* (10), *B* (11), *C* (12), *D* (13), *E* (14) and *F* (15). In other words hexadecimal is nothing more than a different way of writing numbers down -- for example instead of 123 in decimal we can write 7B in hexadecimal (to prevent confusion programmers frequently prefix hexadecimal numbers with `0x`, `#` and similar symbols, because oftentimes a hexadecimal number may only contain digits 0 - 9 and could be confused with a decimal number). Why is hexadecimal so special? Why 16? Why not just use normal decimal numbers? Well, this is out of convenience -- 16 is not an arbitrary number, it is a power of 2 (2^4 = 16); now since digital computers typically work with bits, i.e. 1s and 0s, groups of bits form binary numbers and these are (unlike decimal numbers) very easily converted to and from hexadecimal (exactly because the base 16 is a power of two base): it turns out that 4 bits (i.e. a group of 4 "1s and 0s") always convert exactly to one hexadecimal digit and vice versa, which is very nice and simplifies mental calculations. It also formats numbers nicely -- 8 bits will always be exactly 2 hexadecimal digits etc. That's basically all.

Hexadecimal is so widespread in programming that programmers often use the term "hex" or "hexadecimal" data to just mean "binary" data, e.g. as in "hex editor".

Let's try to clarify it all with a table:

| decimal | binary (2^1) | octal (2^3) | hexadecimal (2^4) |
| ------- | ------------ | ----------- | ----------- |
| 0       | 0            | 0           | 0           |
| 1       | 1            | 1           | 1           |
| 2       | 10           | 2           | 2           |
| 3       | 11           | 3           | 3           |
| 4       | 100          | 4           | 4           |
| 5       | 101          | 5           | 5           |
| 6       | 110          | 6           | 6           |
| 7       | 111          | 7           | 7           |
| 8       | 1000         | 10          | 8           |
| 9       | 1001         | 11          | 9           |
| 10      | 1010         | 12          | A           |
| 11      | 1011         | 13          | B           |
| 12      | 1100         | 14          | C           |
| 13      | 1101         | 15          | D           |
| 14      | 1110         | 16          | E           |
| 15      | 1111         | 17          | F           |
| 16      | 10000        | 20          | 10          |
| 17      | 10001        | 21          | 11          |
| 18      | 10010        | 22          | 12          |

A key observation to make is that a group of 4 binary digits will always directly correspond to one hexadecimal digit and vice versa according to the table above, so for example a binary number 00101110 will be converted to hexadecimal number 2E because 0010 translates to 2 and 1110 translates to E. Also notice this doesn't work the same with conversions to/from decimal numbers. As a programmer you should memorize the 16 pairs of hex digits and binary quadruplets so that you can quickly convert numbers in your head.

The conversions work as in any other base, basically just remember this: *N*th digit from the right (starting with 0) says how many "16 to N"s there are. So for example a hexadecimal number E0A3 has 3 "16^0"s (1s), 10 (A) "16^1"s (16s), 0 "16^2"s (256s) and 14 "16^3"s (4096s), that's 3 * 1 + 10 * 16 + 0 * 256 + 14 * 4096 = 57507. Is it difficult? No.

Some **funny hexadecimal values** that are also English words at the same time and which you may include in your programs for the lulz include: `abba`, `ace`, `add`, `babe`, `bad`, `be`, `bee`, `beef`, `cab`, `cafe`, `dad`, `dead`, `deaf`, `decade`, `facade`, `face`, `fece5` `fee`, `feed`. You may also utilize digits here (see also leet, recall the famous number `80085` that looks like `BOOBS`); `0` = `O`, `1` = `I`/`l`, `2` = `Z`, `4` = `A` (already available though), `5` = `S`, `6` = `G`, `8` = `B` (also already available). Then you get many more words, for example `0b5e55ed`, `0be5e`, `0ff1c1a1`, `101`, `105e`, `1061ca1`, `16100`, `1ad1e5`, `1dea1`, `1e6a1`, `2e1da`, `5a661e5`, `5c1f1`, `50c10b101061ca1`, `60061e`, `600d`, `600fed`, `601d`, `601f`, `60d`, `6a55`, `a1d5`, `a55`, `a5c11`, `a5oc1a1`, `ac1d`, `acce551b1e`, `ad01f`, `b00b1e5`, `b00b5`, `b055`, `b0d1e5`, `b100d`, `b101061ca1`, `b10b`, `b1a5ed`, `b1ade`, `b1e55ed`, `ba115`, `ba5ed`, `bad6e`, `bada55`, `c001`, `c0de`, `c10aca`, `c1a551f1ed`, `ca6ed`, `cab1e`, `caca0`, `d06`, `d15ab1ed`, `d15ea5e`, `d1a106`, `d1ab10`, `ed1b1e`, `f001`, `f00d`, `f1a6`, `f1dd1e`, `f1ea5`, `fa151f1ab1e`, `fa6`, `faece5`, `f06` etc.

## See Also

- binary