Ever wondered how binary numbers work?

When we think about numbers, we often picture them in our familiar decimal system (base 10), consisting of digits from 0 to 9. However, in the world of computers, the fundamental language is binary (base 2), which uses just two digits: 0 and 1. In this article, we will cover the most basic aspects of binary numbers and how they work.

What binary numbers are and how they represent values using only 0s and 1s

Binary numbers, often referred to as "base-2" numbers, are a fundamental concept in computer science and digital electronics. Unlike the decimal system, which uses 10 digits (0-9), binary numbers employ just two digits: 0 and 1. Each digit in a binary number represents a power of 2, just as each digit in a decimal number represents a power of 10. This means that binary numbers are composed of powers of 2, making them highly suitable for representing values in electronic circuits, where "on" and "off" states are fundamental.

Binary Digits (Bits)

The individual units in a binary number are called "bits," short for "binary digits." A single bit can have one of two values: 0 or 1. These values are equivalent to "off" and "on" states in the context of digital circuits, making binary a natural choice for encoding electronic information. Bits can be thought of as the smallest pieces of information in a binary number.

Single-Bit Set Binary Numbers

Binary numbers containing only a single bit set are important because they are easy to understand and you can use them as building blocks to perform more complex operations.

Binary RepresentationDecimal Representation
00000012⁰ = 1
00000102¹ = 2
00001002² = 4
00010002³ = 8
00100002⁴ = 16
01000002⁵ = 32
10000002⁶ = 64

Converting Decimal to Binary

To represent values using binary numbers, you can convert decimal numbers into their binary equivalents.

You can use an intuitive approach, start counting all numbers and put them in the binary system subtracting 1 from the current decimal number. For example, to convert 5 to binary, you can count as follows:

  1. 5 - 1 -> 1 binary + 4 decimal
    1 decimal is converted to 1 in binary representation
  2. 4 - 1 -> 10 binary + 3 decimal
    When you add 1 to a binary number that is originally 1, the result becomes 10 in binary representation. This is because each digit position in binary can hold only one unit or bit, and when you add 1 to a position already occupied by 1, it carries over to the next position, resulting in 10.
  3. 3 - 1 -> 11 binary + 2 decimal
    When you add 1 to the binary number 10, the result becomes 11 in binary representation. This is because the first position in binary initially holds 0, leaving space to accommodate one more unit. Adding 1 to that position fills the available space, resulting in 11.
  4. 2 - 1 -> 100 binary + 1 decimal
    When adding 1 to the binary number 11, it results in 100. This occurs because the binary number 11 cannot accommodate the additional 1 value within its current position, so all the digits must shift from right to left. This behavior is analogous to adding a decimal to a 999 number, which becomes 1000 in decimal notation. In both cases, when a number reaches its maximum value within a digit's position, carrying over to the next position is necessary to represent the increase.
  5. 1 - 1 -> 101 binary + 0 decimal
    Finally, when you add the last unit to the binary number 100, it becomes 101, which is the binary representation of the decimal number 5.

This approach is easy to understand but it becomes impractical when dealing with large numbers because you will have to count every single unit to reach the final result.

An alternative approach to understanding this conversion is to decompose the decimal number into a sum of powers of 2. Each of these powers of two corresponds to a single-bit set binary number, which can be straightforwardly combined as shown in the table below.

Binary RepresentationDecimal valuepower of 2 decomposition
1015 (4 + 1)5 (2² + 2⁰)
110113 (8 + 4 + 1)13 (2³ + 2² + 2⁰)
10110145 (32 + 8 + 4 + 1)45 (2⁵ + 2³ + 2² + 2⁰)

Those methods are good for understanding how binary numbers work and can be converted. However, for a more efficient alternative, you can use some well-established algorithms like the 'Divide and Conquer' method.

The Divide and Conquer Method

The divide and Conquer method consists of recursively dividing the number by 2 and keeping track of the remainder. The binary representation is built by recording these remainders in reverse order. Let's take a closer look step by step in the following example.

To convert 13 into binary:

  1. 13 / 2 = 6 with a remainder of 1

  2. 6 / 2 = 3 with a remainder of 0

  3. 3 / 2 = 1 with a remainder of 1

  4. 1 / 2 = 0 with a remainder of 1

The process stops when the quotient becomes 0, and you are left with the remainders, which, when read from bottom to top, give you the binary representation: 1101.

This algorithm removes dramatically the number of steps taken and can be easily
written in any programming language like the javascript (why not?) example below.

function decimalToBinary(decimal) {
  if (decimal === 0) {
    return "0";
  }

  let binary = "";
  while (decimal > 0) {
    // Step 1: Divide by 2 and get the quotient and remainder
    const quotient = Math.floor(decimal / 2);
    const remainder = decimal % 2;

    // Step 2: Append the remainder to the left of the binary representation
    binary = remainder + binary;

    // Step 3: Update the decimal with the quotient for the next iteration
    decimal = quotient;
  }

  return binary;
}

const decimalNumber = 13;
const binaryRepresentation = decimalToBinary(decimalNumber);
console.log(`Decimal ${decimalNumber} is binary ${binaryRepresentation}`);

As the Divide and Conquer is recursive by definition, it's straightforward to implement a recursive function for the task as well.

function decimalToBinaryRecursive(decimal) {
  // Stop condition
  if (decimal === 0) {
    return "";
  }

  // Recursive step: prepend the remainder of the quotient in each iteration
  return decimalToBinaryRecursive(Math.floor(decimal / 2)) + (decimal % 2);
}

Converting binary into decimal

Now that you know everything about binary numbers you can easily infer that to transform a binary into a decimal you can just decompose binaries in powers of two and explicitly sum them.

Let's say we have the following binary number 110101 and you want to know which number this represents in decimal notation. You could easily sum the base two powers like this:

110101 => 1.2⁵ + 1.2⁴ + 0.2³ + 1.2² + 0.2¹ + 1.2⁰
110101 => 32 + 16 + 0 + 4 + 0 + 1
110101 => 53

Ok! That's nice, but there exists a more efficient approach called Horner's Method.

The Horner's Method

Horner's method is an algorithm to convert numbers in any base to its decimal notation. This method is based on Horner's rule which was primarily used for polynomial evaluation (boring I know 🥱). All you need to know is that this rule states that a polynomial can be written in its nested form as follows:

$${\displaystyle {\begin{aligned}a_{0}&+a_{1}x+a_{2}x^{2}+a_{3}x^{3}+\cdots +a_{n}x^{n}\\&=a_{0}+x{\bigg (}a_{1}+x{\Big (}a_{2}+x{\big (}a_{3}+\cdots +x(a_{n-1}+x\,a_{n})\cdots {\big )}{\Big )}{\bigg )}\end{aligned}}}$$

Let's use the same conversion with our polynomial for the 110101 binary

110101 => 1.2⁵ + 1.2⁴ + 0.2³ + 1.2² + 0.2¹ + 1.2⁰
110101 => 1 + 2(0 + 2(1 + 2( 0 + 2(1 + 2(1))))))

I know it's hard to understand with all those parentheses signs so we can reverse and detach the important numbers.

110101 => ((((((1)2 + 1)2 + 0)2 + 1)2 + 0)2 + 1)

If you pay attention the the ones and zeroes in bold you will notice that we have decomposed our binary number aka polynomial in a way we don't need to perform exponential operations anymore. We can use just sums and multiplications instead.

In terms of an algorithmic approach, the steps are straightforward:

  1. Retrieve the leftmost value.

  2. Multiply by 2.

  3. Add the subsequent value.

  4. Repeat steps 2 and 3 until the end.

Here is a simple JavaScript implementation.

function binaryToDecimal(binary) {
  let accumulator = 0;

  for (let i = 0; i < binary.length; i++) {
    // Multiply the accumulator by 2 and add the current binary digit
    accumulator = accumulator * 2 + binary[i];
  }

  return accumulator;
}

//   Example usage:
const binaryNumber = [1, 1, 0, 1, 0, 1]; // I'm using array because I want to avoid string conversions
const decimalRepresentation = binaryToDecimal(binaryNumber);

console.log(
  `Binary ${binaryNumber.join("")} is decimal ${decimalRepresentation}`
);

Conclusion

Alright, that's all I had to show you. We dive into the binary numbers realm, flipping them back and forth between decimals like it's a piece of cake 🎂.

As a challenge, you can try to apply those conversions to other notations like hexadecimal numbers.

Please, let me know if you are up for more content like that.

👋👋👋

1
Subscribe to my newsletter

Read articles from Eduardo Wronscki directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Eduardo Wronscki
Eduardo Wronscki

Hey there! 👋🏽 I'm a tech-savvy software engineer from Brazil. When I'm not crafting solutions or exploring new tech realms, I'm likely daydreaming about my next beach escape or scouting hidden food gems. Whether it's debugging intricate lines of code or discovering delicious local flavors, I'm all about diving into life's exciting experiences. 🇧🇷 👨‍💻 🏝️ 🌮