Skip to main content

Discrete Mathematics for Computing (Draft)

Section 1.4 Properties of Binary, Octal, and Hexadecimal Systems

In this section we’ll explore some of the properties of the binary, octal, and hexadecimal number systems. The majority of the section will work with the binary number system, but then we’ll explore its connections to the octal and hexidecimal systems as a way to motivate why they are used.

Subsection 1.4.1 Properties of Binary Numbers

As we’ve discussed, the binary number system uses only the two digits \(0\) and \(1\text{.}\) These binary digits are commonly referred to as bits. Consider the following questions associated with binary numbers.

Example 1.4.1. Largest and Smallest.

What are the smallest and largerst positive integers representable by and \(8\)-bit binary number?
Solution.
The smallest positive integer would be \(\left(00000000\right)_{2}\text{,}\) or more simply \(\left(0\right)_{10}\text{.}\) The largest positive integer would be \(\left(11111111\right)_{2}\text{,}\) which is \(\left(255\right)_{10}\text{.}\) We can see this by evaluating the full expansion,
\begin{equation*} 1\cdot 2^7 + 1\cdot 2^6 + 1\cdot 2^5 + 1\cdot 2^4 + 1\cdot 2^3 + 1\cdot 2^2 + 1\cdot 2^1 + 1\cdot 2^0 \end{equation*}
or by recognizing that this is equivalent to \(2^8 - 1\text{.}\)

Example 1.4.2. Tracking Time.

Approaching the year 2000, most computers had a 32-bit processor. Knowing also that computers typically store time in number of seconds elapsed since midnight January 1, 1970, how close were we to computers not being able to tell the time? That is, when would the number of seconds elapsed since midnight on January 1, 1970 become too large to store as a 32-bit binary number?
Solution.
The largest 32-bit positive integer is equivalent to the decimal integer \(2^{32} - 1\text{.}\) There are about 365 days each year, 24 hours in each day, 60 minutes in each hour, and 60 seconds in each minute. Using this, computers could successfully keep time for
\begin{equation*} \displaystyle{\frac{2^{32} - 1}{365\cdot 24\cdot 60\cdot 60}} \approx 136 \text{ years} \end{equation*}
Computers’ timekeeping was never in any real danger, but now with 64-bit processors, we won’t need to worry for over half a trillion years!
Up until now, we’ve been working only with positive integer values. Computers are certainly capable of handling more general values -- indeed, negative integers and floating point numbers are all data types recognized by computers. How do they store such values?
If we would like to store a signed integer (allowing for both positive and negative values), then we need to reserve one digit for encoding the sign on the value. One way to do this is to use the left-most bit to encode the sign (0 is positive, 1 is negative), and all remaining bits to encode the absolute value of the number encoded. This representation scheme is called sign-magnitude, but there are other methods such as one’s complement and two’s complement.

Example 1.4.3. Largest and Smallest Signed Integers.

What are the largest and smallest representable 8-bit signed integers?
Solution.
The largest 8-bit signed integer would be encoded as \(\left(01111111\right)_{2}\text{,}\) which is equivalent to \(\left(127\right)_{10}\text{.}\) The smallest integer would be encoded as \(\left(11111111\right)_{2}\text{,}\) which represents \(\left(-127\right)_{10}\) under the sign-magnitude scheme.
An interesting property of sign-magnitude is that there are two ways to represent \(\left(0\right)_{10}\text{!}\)
Considering the consequences associated with different number encoding implementations is beyond the scope of this course. Interested students should look for a course in Numerical Analysis, which will cover methods for representing floating point numbers, floating point arithmetic, and more.

Subsection 1.4.2 Connecting Binary to Octal and Hexadecimal

Perhaps you are convinced that the binary system is important because machines lack fingers and toes to count on, but why are the octal and hexadecimal systems also used? Binary encodings can be quite lengthy. To represent the number \(\left(999\right)_{10}\text{,}\) we need \(10\) bits. Its difficult to extract any meaning from such a number by looking at its binary representation. By grouping bits together, we can achieve more efficient encodings. Additionally, since we are simply grouping adjacent bits together with one another, we can quickly convert between binary and either octal, hexadecimal, or even whatever fancy name you want to give to a base-32 or base-64 numbering system. Let’s take a look at an example below.

Example 1.4.4. Binary to Hexadecimal.

Convert \(\left(11011001\right)_{2}\) to its hexadecimal equivalent.
Solution.
Start by grouping sets of four consecutive bits together. since every four bits can be encoded using a single hexadecimal digit. We must do this grouping beginning with the rightmost bit. Once we have the bits grouped, then we can convert the groups of four bits to their equivalent hexadecimal digits independently of one another.
\begin{align*} \left(11011001\right)_{2} \amp = \left(\underbrace{1101}_{D_{16}}\underbrace{1001}_{9_{16}}\right)_{2}\\ \amp = \left(D9\right)_{16} \end{align*}

Example 1.4.5. Binary to Octal.

Convert \(\left(11011001\right)_{2}\) to its octal equivalent.
Solution.
Similarly to the previous example, we’d like to group our bits together. Here, we would like to create groups of three bits (since we are converting to base-8, and \(2^3 = 8\)), but our binary number is only 8-bits in length. We’ll start by padding the number with an extra 0 on the left. Do you agree that it doesn’t change the value of the encoded number? Once we’ve done this, the conversion is just like before. We convert each group of three consecutive bits into the corresponding octal digit independently of the other groups.
\begin{align*} \left(11011001\right)_{2} \amp = \left(011011001\right)_{2}\\ \amp = \left(\underbrace{011}_{3_{8}}\underbrace{011}_{3_{8}}\underbrace{001}_{1_{8}}\right)_{2}\\ \amp = \left(331\right)_{8} \end{align*}

Example 1.4.6. Hexadecimal to Binary.

Convert \(\left(8A2C\right)_{16}\) to its binary equivalent.
Solution.
We are now just working backwards. Each hexadecimal digit will be encoded by four bits in the corresponding binary representation. That is, we’ll expand each hexadecimal digit into four bits in the binary representation. Similar to the previous examples, this expansion can happen independently for each hexadecimal digit.
\begin{align*} \left(8A2C\right)_{16} \amp = \left(\underbrace{8}_{1000_{2}}\underbrace{A}_{1010_{2}}\underbrace{2}_{0010_{2}}\underbrace{C}_{1100_{2}}\right)_{16}\\ \amp = \left(1000101000101100\right)_{2} \end{align*}
Did you find those conversions to be much easier than the conversions we’ve made between generic pairs of bases?

Subsection 1.4.3 Conclusion

There’s nothing here yet.