Number Bases and Binary Conversion
6 min read · Free to read
A number and the way we write it are not the same thing. The quantity we call one hundred and eighty-two is written 182 in decimal, 10110110 in binary, 266 in octal, and B6 in hexadecimal, and all four are the same number wearing different clothes. Once that separation is clear, base conversion stops being a trick to memorise and becomes what it really is: translating between notations for a quantity that never changed.
This matters in computing because machines store everything in base 2 while people read base 10, and hexadecimal exists as a compact shorthand between them. This guide starts from what positional notation claims, then works through the standard bases and the conversion algorithms in each direction. It closes with two's complement, the convention that lets a fixed-width binary field represent negative numbers without a sign symbol.
What positional notation means
In a positional system with base b, the position of a digit determines the power of b it carries. The rightmost digit is multiplied by b^0, the next by b^1, then b^2, and so on. So the decimal string 3721 abbreviates 3 times 1000 plus 7 times 100 plus 2 times 10 plus 1, which is 3 times 10^3 plus 7 times 10^2 plus 2 times 10^1 plus 1 times 10^0. Nothing about this reasoning depends on the number 10.
Two rules follow immediately. The digits available in base b are exactly 0 through b-1, since a digit equal to b would be a carry into the next position. And every non-negative integer has exactly one representation in base b with no leading zeros, which makes conversion well defined rather than a matter of choice. Bases above 10 need extra symbols, which is why hexadecimal borrows the letters A through F for the values 10 through 15.
- Digit at position i counts b^i, with positions numbered from 0 on the right.
- Valid digits in base b are 0 through b-1.
- Every non-negative integer has one representation per base, up to leading zeros.
- Bases above 10 use letters: A is 10, B is 11, up to F which is 15.
Binary, octal, and hexadecimal
Binary is base 2, so its digits are just 0 and 1 and its place values are the powers of 2: 1, 2, 4, 8, 16, 32, 64, 128 and onwards. A single binary digit is a bit, eight of them form a byte, and four of them form a nibble. Binary is what hardware actually implements, since a two-state device is the easiest thing to build reliably.
Octal is base 8 and hexadecimal is base 16. Both exist because binary strings are long and error-prone to read, and both are powers of 2, which makes conversion to and from binary purely mechanical. Hexadecimal has become the default for memory addresses, colour codes, and byte dumps, because each hex digit is exactly four bits, so one byte is always two hex digits.
- Binary place values are 1, 2, 4, 8, 16, 32, 64, 128, and so on.
- One hex digit equals exactly 4 bits; one octal digit equals exactly 3 bits.
- A byte is 8 bits, so exactly 2 hex digits.
- Hex digits run 0 to 9 then A to F, covering the values 0 through 15.
Converting to decimal: expand the places
Going from any base into decimal is direct application of the definition. Multiply each digit by its place value and add. For the binary string 10110110, the set bits sit at positions 7, 5, 4, 2 and 1, so the value is 128 plus 32 plus 16 plus 4 plus 2, which is 182. Only the positions holding a 1 contribute, which makes binary expansion faster than it looks.
The same method handles any base. The hexadecimal string B6 is B times 16 plus 6, and since B stands for 11 that is 176 plus 6, which is 182. The octal string 266 is 2 times 64 plus 6 times 8 plus 6, which is 128 plus 48 plus 6, again 182. All three strings denote the same quantity, now checked digit by digit.
Converting from decimal: repeated division
To go from decimal into base b, divide repeatedly by b and collect the remainders. Each remainder is a digit, produced from the least significant end first, so the answer is read bottom to top once the quotient reaches 0. The reason it works is that dividing by b shifts the representation one place right, and the remainder is exactly the digit that falls off.
Convert 182 to binary: 182 divided by 2 is 91 remainder 0; 91 divided by 2 is 45 remainder 1; 45 divided by 2 is 22 remainder 1; 22 divided by 2 is 11 remainder 0; 11 divided by 2 is 5 remainder 1; 5 divided by 2 is 2 remainder 1; 2 divided by 2 is 1 remainder 0; 1 divided by 2 is 0 remainder 1. Reading the remainders upwards gives 10110110, which matches the expansion above. The same loop with divisor 16 gives 182 as B6, and with divisor 8 gives 266.
- Divide by the target base, record the remainder, repeat with the quotient.
- Stop when the quotient reaches 0.
- Read the remainders in reverse: last one found is the leading digit.
- Always confirm by expanding the result back into decimal.
Binary to hex and octal by grouping
Between binary and any base that is a power of 2, no arithmetic is needed at all. Because 16 is 2^4, each hexadecimal digit corresponds to a fixed block of 4 bits, so you group the binary string into 4-bit blocks starting from the right, padding the leftmost block with zeros if necessary, and translate each block on its own. The string 10110110 splits into 1011 and 0110, which are 11 and 6, so the hexadecimal form is B6.
Octal works identically with 3-bit groups, since 8 is 2^3. The same string splits from the right into 10, 110 and 110, giving digits 2, 6 and 6, so the octal form is 266. The process reverses just as easily: expand each hex digit into its 4-bit pattern and concatenate. The hexadecimal number 2F9 becomes 0010, 1111, 1001, so 1011111001 after dropping leading zeros, and expanding that binary string confirms the value 761, which matches 2 times 256 plus 15 times 16 plus 9.
- Group from the right, never from the left, and pad the leading group with zeros.
- 4 bits per hex digit, 3 bits per octal digit.
- Reverse the process by expanding each digit into its fixed bit pattern.
- Grouping only works when one base is a power of the other.
Two's complement: negative numbers in fixed width
A binary field of fixed width has no minus sign available, so hardware encodes negatives by convention. The dominant convention is two's complement: to negate a number, invert every bit and add 1. In 8 bits, 37 is 00100101; inverting gives 11011010; adding 1 gives 11011011. That pattern is the 8-bit representation of -37, and read as an unsigned value it is 219, which is 256 minus 37, the pattern the convention is named after.
The rule for reading a two's complement value is that the leading bit carries a negative weight. In 8 bits the top place counts -128 rather than +128, so 11011011 is -128 plus 64 plus 16 plus 8 plus 2 plus 1, which is -37, confirming the encoding. This makes the leading bit a sign indicator: 0 for non-negative, 1 for negative. An n-bit field therefore covers -2^(n-1) through 2^(n-1) - 1, so 8 bits span -128 through 127. The range is asymmetric because zero occupies a non-negative pattern, which is why the most negative value has no positive counterpart.
- Negate by inverting all bits and adding 1.
- The leading bit carries weight -2^(n-1), so it doubles as a sign bit.
- An n-bit field represents -2^(n-1) through 2^(n-1) - 1.
- 8 bits give -128 through 127, asymmetric because zero counts as non-negative.
Frequently asked questions
How do I convert a decimal number to binary?
Divide repeatedly by 2, recording each remainder, until the quotient is 0, then read the remainders in reverse. For 182 the remainders are 0, 1, 1, 0, 1, 1, 0, 1, which read upwards give 10110110.
Why is hexadecimal used so often in computing?
Because 16 is 2^4, one hex digit stands for exactly four bits and one byte is exactly two hex digits. That fixed correspondence lets you convert by grouping instead of by arithmetic, and it makes long binary values far shorter to read and less error-prone to transcribe.
How does two's complement represent a negative number?
Invert every bit of the magnitude and add 1. In 8 bits, 37 is 00100101, inverting gives 11011010, and adding 1 gives 11011011 for -37. Reading it back, the leading bit counts -128, so the value is -128 plus 91, which is -37.
What range does an n-bit two's complement number cover?
From -2^(n-1) to 2^(n-1) - 1. For 8 bits that is -128 through 127. The range is asymmetric because the zero pattern uses one of the non-negative encodings, leaving one more pattern available on the negative side.