yaobin.wen

Yaobin's Blog

View on GitHub
30 July 2023

Representing signed numbers

by yaobin.wen

1. Number circle

In order to better understand the representations of signed numbers and their arithmetics, we need to have the concept of a “number circle.”

We all know what a “number line” is. Wikipedia provides the following explanation:

A number line is a graphical representation of a straight line that serves as spatial representation of numbers, usually graduated like a ruler with a particular origin point representing the number zero and evenly spaced marks in either direction representing integers, imagined to extend infinitely.

Because a number line is usually a straight line that doesn’t have boundaries, it can represent the numbers between \(-\infty\) and \(+\infty\).

However, on a computer, we don’t have unlimited amount of storage to represent infinity. When talking about number representation on computers, we need to focus on a \(N\)-bit storage where \(N\) is a positive integer such as 1, 2, 4, 8, etc. (Surely \(N\) can be any arbitrary positive integer such as 3 or 5. In fact, I’m going to use a 3-bit storage in the subsequent sections to talk about the signed number representation.)

Because \(N\) is a finite number, the smallest binary number it can represent is \((000\ldots0)_2\) where there are \(N\) 0s, and the largest binary number it can represent is \((111\ldots1)_2\) where there are \(N\) 1s. We can draw these binary numbers on a line segment which starts with \((000\ldots0)_2\) and ends with \((111\ldots1)_2\), as shown below:

N-bit line segment

However, if we are pointing at the largest number \((111\ldots1)_2\) and then move one position to the right, what will we get? Because moving one position towards the right direction means adding \(1\) to the previous number, moving one position to the right beyond the number \((111\ldots1)_2\) means adding \((1)_2\) to \((111\ldots1)_2\). “\((111\ldots1)_2 + 1\)” will cause overflow: the result is \((000\ldots0)_2\) and a carry bit \((1)_2\). But because we are talking about the \(N\)-bit storage here, we have to discard the carry bit \((1)_2\) because it doesn’t belong to any bit of this \(N\)-bit storage. As a result, the result of “\((111\ldots1)_2 + 1\)” is \((000\ldots0)_2\) again: we suddenly wrap around the right-most end of the line segment and go back to the left-most end of the line segment. This is similar to the “screen wraparound” in some early video games such as Asteroids. Because of this wraparound, it’s more accurate to use a “number circle” (see note below *) to represent the \(N\)-bit storage:

N-bit number circle

When \(N=3\), the number circle looks like as follows:

3-bit number circle

Note (*):

2. Encoding

All of the signed number representations that we talk about in this article are essentially methods of encoding abstract mathematical signed numbers into binaries.

Therefore, it makes sense to ask “What is the 4-bit sign-magnitude representation of \((7)_{10}\)?”, or “What is the 8-bit two’s complement representation of \((-3)_{10}\)?”. In these questions, we ask “how to encode abstract mathematical signed numbers \((7)_{10}\) and \((-3)_{10}\) into a specific binary form (i.e., 4-bit binary and 8-bit binary)”.

However, strictly speaking, it makes no sense to me to ask “What is the two’s complement representation of \((1101)_2\) which itself is in two’s complement representation?” because:

However, sometimes when we ask “What is the two’s complement representation of \((1101)_2\) which itself is in two’s complement representation?”, we are actually asking “The two’s complement representation \((1101)_2\) represents the number \((-3)_{10}\). What is the two’s complement representation of \((-3)_{10}\)’s additive inverse, i.e., \((3)_{10}\)?” The answer is \((0011)_2\). Personally, I find this way of asking question is confusing, so although I understand some people may ask this way, I still don’t prefer this kind of question.

3. Sign–magnitude

The first method of encoding mathematical numbers is the sign-magnitude representation. It is also called sign-and-magnitude or signed magnitude. For an \(N\)-bit storage, the most significant bit (MSb) is used to indicate the sign of the number:

The remaining \(N-1\) bits are used to represent the magnitude (aka “absolute value”) of the number.

For example, when \(N=3\):

Binary Sign Magnitude Signed decimal
\((000)_2\) + \((00)_2\) \((+0)_{10}\)
\((001)_2\) + \((01)_2\) \((+1)_{10}\)
\((010)_2\) + \((10)_2\) \((+2)_{10}\)
\((011)_2\) + \((11)_2\) \((+3)_{10}\)
\((100)_2\) - \((00)_2\) \((-0)_{10}\)
\((101)_2\) - \((01)_2\) \((-1)_{10}\)
\((110)_2\) - \((10)_2\) \((-2)_{10}\)
\((111)_2\) - \((11)_2\) \((-3)_{10}\)

The number circle for the 3-bit storage is as follows:

3-bit number circle for sign-magnitude

The advantage of the sign-magnitude representation is that it has an intuitive mapping to how we represent signed decimal numbers in everyday use, because in our daily life we also use the sign-magnitude representation to denote decimal numbers. For example, to represent the value “positive ten”, we simply write down the symbol + followed by the decimal magnitude 10; if we want to represent the value “negative ten”, we simply write down the symbol - followed by the decimal magnitude 10.

However, the sign-magnitude representation has drawbacks too:

3.1 Addition

Adding signed numbers in sign-magnitude representation requires handling the signs explicitly and performing magnitude addition or subtraction based on the signs.

When the two numbers have the same signs (either both positive or both negative), adding them only needs to add the magnitudes and preserve the sign bit in the result. For example:

In the case of same signs, if the addition of the magnitudes produces a carry bit in the most significant bits, this indicates an overflow or underflow, i.e., the addition exceeds the largest number or the smallest number that these \(N\) bits can describe. Unfortunately, I haven’t found the documents about how to handle the overflow, possibly because sign-magnitude representation has become much less popular so the related information is no longer that available than the early days. However, by thinking about it, I think it’s up to the hardware/software designer to decide how to handle it, and there can be three ways:

In this article, I’m going to use the second way: Overflow on the positive half or the negative half on the number circle. For example:

This can be illustrated as follows:

3-bit number circle for sign-magnitude addition

When the two numbers have different signs (i.e., one positive and one negative), adding them is done as follows:

Because zero has two sign-magnitude representations, we also need to handle zero specially, possibly by normalizing the result to always using \(0\).

3.2 Addition using sign-magnitude

The following table deals with overflow/underflow in the second way, i.e., overflowing/underflowing in the positive/negative half of the number circle.

Addend Addend Sum Carry bits (*) Decimal Over-/underflow Note
\((000)_2\) \((000)_2\) \((000)_2\) \((00x)_2\) \(0 + 0 = 0\) N/A  
\((000)_2\) \((001)_2\) \((001)_2\) \((00x)_2\) \(0 + 1 = 1\) N/A  
\((000)_2\) \((010)_2\) \((010)_2\) \((00x)_2\) \(0 + 2 = 2\) N/A  
\((000)_2\) \((011)_2\) \((011)_2\) \((00x)_2\) \(0 + 3 = 3\) N/A  
\((000)_2\) \((100)_2\) \((000)_2\) \((00x)_2\) \(0 + (-0) = 0\) N/A Normalized to \(0\).
\((000)_2\) \((101)_2\) \((101)_2\) \((00x)_2\) \(0 + (-1) = -1\) N/A  
\((000)_2\) \((110)_2\) \((110)_2\) \((00x)_2\) \(0 + (-2) = -2\) N/A  
\((000)_2\) \((111)_2\) \((111)_2\) \((00x)_2\) \(0 + (-3) = -3\) N/A  
             
\((001)_2\) \((001)_2\) \((010)_2\) \((01x)_2\) \(1 + 1 = 2\) N/A  
\((001)_2\) \((010)_2\) \((011)_2\) \((00x)_2\) \(1 + 2 = 3\) N/A  
\((001)_2\) \((011)_2\) \((000)_2\) \((11x)_2\) \(1 + 3 = 0\) Overflow (1)
\((001)_2\) \((100)_2\) \((001)_2\) \((00x)_2\) \(1 + (-0) = 1\) N/A  
\((001)_2\) \((101)_2\) \((000)_2\) \((01x)_2\) \(1 + (-1) = 0\) N/A  
\((001)_2\) \((110)_2\) \((101)_2\) \((00x)_2\) \(1 + (-2) = -1\) N/A  
\((001)_2\) \((111)_2\) \((110)_2\) \((11x)_2\) \(1 + (-3) = -2\) N/A  
             
\((010)_2\) \((010)_2\) \((000)_2\) \((10x)_2\) \(2 + 2 = 0\) Overflow (2)
\((010)_2\) \((011)_2\) \((001)_2\) \((10x)_2\) \(2 + 3 = 1\) Overflow (3)
\((010)_2\) \((100)_2\) \((010)_2\) \((00x)_2\) \(2 + (-0) = 2\) N/A  
\((010)_2\) \((101)_2\) \((001)_2\) \((00x)_2\) \(2 + (-1) = 1\) N/A  
\((010)_2\) \((110)_2\) \((000)_2\) \((10x)_2\) \(2 + (-2) = 0\) N/A  
\((010)_2\) \((111)_2\) \((101)_2\) \((10x)_2\) \(2 + (-3) = -1\) N/A  
             
\((011)_2\) \((011)_2\) \((010)_2\) \((11x)_2\) \(3 + 3 = 2\) Overflow (4)
\((011)_2\) \((100)_2\) \((011)_2\) \((00x)_2\) \(3 + (-0) = 3\) N/A  
\((011)_2\) \((101)_2\) \((010)_2\) \((11x)_2\) \(3 + (-1) = 2\) N/A  
\((011)_2\) \((110)_2\) \((001)_2\) \((10x)_2\) \(3 + (-2) = 1\) N/A  
\((011)_2\) \((111)_2\) \((000)_2\) \((11x)_2\) \(3 + (-3) = 0\) N/A  
             
\((100)_2\) \((100)_2\) \((000)_2\) \((00x)_2\) \(-0 + (-0) = 0\) N/A Normalized to \(0\).
\((100)_2\) \((101)_2\) \((101)_2\) \((00x)_2\) \(-0 + (-1) = -1\) N/A  
\((100)_2\) \((110)_2\) \((110)_2\) \((00x)_2\) \(-0 + (-2) = -2\) N/A  
\((100)_2\) \((111)_2\) \((111)_2\) \((00x)_2\) \(-0 + (-3) = -3\) N/A  
             
\((101)_2\) \((101)_2\) \((110)_2\) \((01x)_2\) \(-1 + (-1) = -2\) N/A  
\((101)_2\) \((110)_2\) \((111)_2\) \((00x)_2\) \(-1 + (-2) = -3\) N/A  
\((101)_2\) \((111)_2\) \((100)_2\) \((11x)_2\) \(-1 + (-3) = -0\) Underflow (5)
             
\((110)_2\) \((110)_2\) \((100)_2\) \((10x)_2\) \(-2 + (-2) = -0\) Underflow (6)
\((110)_2\) \((111)_2\) \((101)_2\) \((10x)_2\) \(-2 + (-3) = -1\) Underflow (7)
             
\((111)_2\) \((111)_2\) \((110)_2\) \((11x)_2\) \(-3 + (-3) = -2\) Underflow (8)

Note (*):

Notes:

4. One’s complement

In a \(N\)-bit one’s complement representation:

For example, when \(N=3\):

Binary Sign Signed decimal
\((000)_2\) + \((+0)_{10}\)
\((001)_2\) + \((+1)_{10}\)
\((010)_2\) + \((+2)_{10}\)
\((011)_2\) + \((+3)_{10}\)
\((100)_2\) - \((-3)_{10}\)
\((101)_2\) - \((-2)_{10}\)
\((110)_2\) - \((-1)_{10}\)
\((111)_2\) - \((-0)_{10}\)

Take \((010)_2\) and \((101)_2\) for examples:

Note that zero still has two representations: \((000)_2\) and \((111)_2\).

The number circle is as follows:

3-bit one's complement number circle

4.1 Addition using one’s complement

Adding two binaries in one’s complement is straightforward. Simply align the values on the least significant bit and add them bit by bit, propagating any carry to the bit one position left. If the carry extends past the end of the word it is said to have “wrapped around”, a condition called an “end-around carry”. When this occurs, the bit must be added back in at the right-most bit.

This adding arithmetics implements the clockwise rotation on the number circle (except at \((111)_2\)). For example:

Here are the addition of 3-bit binaries in one’s complement:

Addend Addend Sum Decimal Note
\((000)_2\) \((000)_2\) \((000)_2\) \(0 + 0 = 0\)  
\((000)_2\) \((001)_2\) \((001)_2\) \(0 + 1 = 0\)  
\((000)_2\) \((010)_2\) \((010)_2\) \(0 + 2 = 2\)  
\((000)_2\) \((011)_2\) \((011)_2\) \(0 + 3 = 2\)  
\((000)_2\) \((100)_2\) \((100)_2\) \(0 + (-3) = -3\)  
\((000)_2\) \((101)_2\) \((101)_2\) \(0 + (-2) = -2\)  
\((000)_2\) \((110)_2\) \((110)_2\) \(0 + (-1) = -1\)  
\((000)_2\) \((111)_2\) \((111)_2\) \(0 + (-0) = -0\)  
         
\((001)_2\) \((000)_2\) \((001)_2\) \(1 + 0 = 1\)  
\((001)_2\) \((001)_2\) \((010)_2\) \(1 + 1 = 2\)  
\((001)_2\) \((010)_2\) \((011)_2\) \(1 + 2 = 3\)  
\((001)_2\) \((011)_2\) \((100)_2\) \(1 + 3 = -3\) Overflow
\((001)_2\) \((100)_2\) \((101)_2\) \(1 + (-3) = -2\)  
\((001)_2\) \((101)_2\) \((110)_2\) \(1 + (-2) = -1\)  
\((001)_2\) \((110)_2\) \((111)_2\) \(1 + (-1) = -0\)  
\((001)_2\) \((111)_2\) \((001)_2\) \(1 + (-0) = 1\) (1)
         
\((010)_2\) \((000)_2\) \((010)_2\) \(2 + 0 = 2\)  
\((010)_2\) \((001)_2\) \((011)_2\) \(2 + 1 = 3\)  
\((010)_2\) \((010)_2\) \((100)_2\) \(2 + 2 = -3\) Overflow
\((010)_2\) \((011)_2\) \((101)_2\) \(2 + 3 = -2\) Overflow
\((010)_2\) \((100)_2\) \((110)_2\) \(2 + (-3) = -1\)  
\((010)_2\) \((101)_2\) \((111)_2\) \(2 + (-2) = -0\)  
\((010)_2\) \((110)_2\) \((001)_2\) \(2 + (-1) = 1\) (2)
\((010)_2\) \((111)_2\) \((010)_2\) \(2 + (-0) = 2\)  
         
\((011)_2\) \((000)_2\) \((011)_2\) \(3 + 0 = 3\)  
\((011)_2\) \((001)_2\) \((100)_2\) \(3 + 1 = -3\) Overflow
\((011)_2\) \((010)_2\) \((101)_2\) \(3 + 2 = -2\) Overflow
\((011)_2\) \((011)_2\) \((110)_2\) \(3 + 3 = -1\) Overflow
\((011)_2\) \((100)_2\) \((111)_2\) \(3 + (-3) = -0\)  
\((011)_2\) \((101)_2\) \((001)_2\) \(3 + (-2) = 1\) (3)
\((011)_2\) \((110)_2\) \((010)_2\) \(3 + (-1) = 2\) (4)
\((011)_2\) \((111)_2\) \((011)_2\) \(3 + (-0) = 3\) (5)
         
\((100)_2\) \((000)_2\) \((100)_2\) \(-3 + 0 = -3\)  
\((100)_2\) \((001)_2\) \((101)_2\) \(-3 + 1 = -2\)  
\((100)_2\) \((010)_2\) \((110)_2\) \(-3 + 2 = -1\)  
\((100)_2\) \((011)_2\) \((111)_2\) \(-3 + 3 = -0\)  
\((100)_2\) \((100)_2\) \((001)_2\) \(-3 + (-3) = 1\) (6) Underflow
\((100)_2\) \((101)_2\) \((010)_2\) \(-3 + (-2) = 2\) (7) Underflow
\((100)_2\) \((110)_2\) \((011)_2\) \(-3 + (-1) = 3\) (8) Underflow
\((100)_2\) \((111)_2\) \((100)_2\) \(-3 + (-0) = -3\) (9)
         
\((101)_2\) \((000)_2\) \((101)_2\) \(-2 + 0 = -2\)  
\((101)_2\) \((001)_2\) \((110)_2\) \(-2 + 1 = -1\)  
\((101)_2\) \((010)_2\) \((111)_2\) \(-2 + 2 = -0\)  
\((101)_2\) \((011)_2\) \((001)_2\) \(-2 + 3 = 1\) (10)
\((101)_2\) \((100)_2\) \((010)_2\) \(-2 + (-3) = 2\) (11) Underflow
\((101)_2\) \((101)_2\) \((011)_2\) \(-2 + (-2) = 3\) (12) Underflow
\((101)_2\) \((110)_2\) \((100)_2\) \(-2 + (-1) = -3\) (13)
\((101)_2\) \((111)_2\) \((101)_2\) \(-2 + (-0) = -2\) (14)
         
\((110)_2\) \((000)_2\) \((110)_2\) \(-1 + 0 = -1\)  
\((110)_2\) \((001)_2\) \((111)_2\) \(-1 + 1 = -0\)  
\((110)_2\) \((010)_2\) \((001)_2\) \(-1 + 2 = 1\) (15)
\((110)_2\) \((011)_2\) \((010)_2\) \(-1 + 3 = 2\) (16)
\((110)_2\) \((100)_2\) \((011)_2\) \(-1 + (-3) = 3\) (17) Underflow
\((110)_2\) \((101)_2\) \((100)_2\) \(-1 + (-2) = -3\) (18)
\((110)_2\) \((110)_2\) \((101)_2\) \(-1 + (-1) = -2\) (19)
\((110)_2\) \((111)_2\) \((110)_2\) \(-1 + (-0) = -1\) (20)
         
\((111)_2\) \((000)_2\) \((111)_2\) \(-0 + 0 = -0\)  
\((111)_2\) \((001)_2\) \((001)_2\) \(-0 + 1 = 1\) (21)
\((111)_2\) \((010)_2\) \((010)_2\) \(-0 + 2 = 2\) (22)
\((111)_2\) \((011)_2\) \((011)_2\) \(-0 + 3 = 3\) (23)
\((111)_2\) \((100)_2\) \((100)_2\) \(-0 + (-3) = -3\) (24)
\((111)_2\) \((101)_2\) \((101)_2\) \(-0 + (-2) = -2\) (25)
\((111)_2\) \((110)_2\) \((110)_2\) \(-0 + (-1) = -1\) (26)
\((111)_2\) \((111)_2\) \((111)_2\) \(-0 + (-0) = -0\) (27)

Notes:

4.2 Subtraction using one’s complement

Subtraction can be implemented by adding the negative counterpart. For example:

However, the subtraction can also be directly calculated this way: Align the values on the least significant bit and subtract, propagating any borrow to the bit one position left. If the borrow extends past the end of the word it is said to have “wrapped around”, a condition called an “end-around borrow”. When this occurs, the bit must be subtracted from the right-most bit to get the correct result.

5. Two’s complement

In two’s complement representation:

For example,

For a 3-bit system, we can encode the 8 numbers differently (Range: \([-4, 3]\))::

Binary Sign Signed decimal
\((000)_2\) + \((0)_{10}\)
\((001)_2\) + \((1)_{10}\)
\((010)_2\) + \((2)_{10}\)
\((011)_2\) + \((3)_{10}\)
\((100)_2\) - \((-4)_{10}\)
\((101)_2\) - \((-3)_{10}\)
\((110)_2\) - \((-2)_{10}\)
\((111)_2\) - \((-1)_{10}\)

The number circle is as follows:

3-bit two's complement number circle

Another way of finding a number’s two complement is: Work right-to-left and write down all digits through when you reach a 1. Then invert the rest of the digits. For example:

5.1 Converting a binary in two’s complement to decimal

Because the most significant bit (MSb) of a binary in two’s complement indicates the sign of the number, when converted to the corresponding decimal number, the value of the sign bit should be positive or negative accordingly. For example:

5.2 Addition using two’s complement

Adding two’s complement numbers requires no special processing even if the operands have opposite signs; the sign of the result is determined automatically. However, the sum may not be valid when an overflow or underflow happens. An overflow/underflow can be determined by the left-most two bits of the carry bits: if they are the same (i.e., both are 0 or both are 1), then no overflow/underflow happens; if they are different (i.e., either 01 or 10), then an overflow/underflow happens.

Here are the addition of 3-bit binaries in two’s complement. The carry bits consist of four bits but the first bit, indicated by x, is not meaningful in this context because the first bits of the two addends don’t receive any carry bit.

Addend Addend Sum Carry bits Decimal Over-/underflow Note
\((000)_2\) \((000)_2\) \((000)_2\) \((000x)_2\) \(0 + 0 = 0\)    
\((000)_2\) \((001)_2\) \((001)_2\) \((000x)_2\) \(0 + 1 = 0\)    
\((000)_2\) \((010)_2\) \((010)_2\) \((000x)_2\) \(0 + 2 = 2\)    
\((000)_2\) \((011)_2\) \((011)_2\) \((000x)_2\) \(0 + 3 = 2\)    
\((000)_2\) \((100)_2\) \((100)_2\) \((000x)_2\) \(0 + (-4) = -4\)    
\((000)_2\) \((101)_2\) \((101)_2\) \((000x)_2\) \(0 + (-3) = -3\)    
\((000)_2\) \((110)_2\) \((110)_2\) \((000x)_2\) \(0 + (-2) = -2\)    
\((000)_2\) \((111)_2\) \((111)_2\) \((000x)_2\) \(0 + (-1) = -1\)    
             
\((001)_2\) \((000)_2\) \((001)_2\) \((000x)_2\) \(1 + 0 = 1\)    
\((001)_2\) \((001)_2\) \((010)_2\) \((001x)_2\) \(1 + 1 = 2\)    
\((001)_2\) \((010)_2\) \((011)_2\) \((000x)_2\) \(1 + 2 = 3\)    
\((001)_2\) \((011)_2\) \((100)_2\) \((011x)_2\) \(1 + 3 = -4\) Overflow (1)
\((001)_2\) \((100)_2\) \((101)_2\) \((000x)_2\) \(1 + (-4) = -3\)    
\((001)_2\) \((101)_2\) \((110)_2\) \((001x)_2\) \(1 + (-3) = -2\)    
\((001)_2\) \((110)_2\) \((111)_2\) \((000x)_2\) \(1 + (-2) = -1\)    
\((001)_2\) \((111)_2\) \((000)_2\) \((111x)_2\) \(1 + (-1) = 0\)    
             
\((010)_2\) \((000)_2\) \((010)_2\) \((000x)_2\) \(2 + 0 = 2\)    
\((010)_2\) \((001)_2\) \((011)_2\) \((000x)_2\) \(2 + 1 = 3\)    
\((010)_2\) \((010)_2\) \((100)_2\) \((010x)_2\) \(2 + 2 = -4\) Overflow (2)
\((010)_2\) \((011)_2\) \((101)_2\) \((010x)_2\) \(2 + 3 = -3\) Overflow (3)
\((010)_2\) \((100)_2\) \((110)_2\) \((000x)_2\) \(2 + (-4) = -2\)    
\((010)_2\) \((101)_2\) \((111)_2\) \((000x)_2\) \(2 + (-3) = -1\)    
\((010)_2\) \((110)_2\) \((000)_2\) \((110x)_2\) \(2 + (-2) = 0\)    
\((010)_2\) \((111)_2\) \((001)_2\) \((110x)_2\) \(2 + (-1) = 1\)    
             
\((011)_2\) \((000)_2\) \((011)_2\) \((000x)_2\) \(3 + 0 = 3\)    
\((011)_2\) \((001)_2\) \((100)_2\) \((011x)_2\) \(3 + 1 = -4\) Overflow (4)
\((011)_2\) \((010)_2\) \((101)_2\) \((010x)_2\) \(3 + 2 = -3\) Overflow (5)
\((011)_2\) \((011)_2\) \((110)_2\) \((011x)_2\) \(3 + 3 = -2\) Overflow (6)
\((011)_2\) \((100)_2\) \((111)_2\) \((000x)_2\) \(3 + (-4) = -1\)    
\((011)_2\) \((101)_2\) \((000)_2\) \((111x)_2\) \(3 + (-3) = 0\)    
\((011)_2\) \((110)_2\) \((001)_2\) \((110x)_2\) \(3 + (-2) = 1\)    
\((011)_2\) \((111)_2\) \((010)_2\) \((111x)_2\) \(3 + (-1) = 2\)    
             
\((100)_2\) \((000)_2\) \((100)_2\) \((000x)_2\) \(-4 + 0 = -4\)    
\((100)_2\) \((001)_2\) \((101)_2\) \((000x)_2\) \(-4 + 1 = -3\)    
\((100)_2\) \((010)_2\) \((110)_2\) \((000x)_2\) \(-4 + 2 = -2\)    
\((100)_2\) \((011)_2\) \((111)_2\) \((000x)_2\) \(-4 + 3 = -1\)    
\((100)_2\) \((100)_2\) \((000)_2\) \((100x)_2\) \(-4 + (-4) = 0\) Underflow (7)
\((100)_2\) \((101)_2\) \((001)_2\) \((100x)_2\) \(-4 + (-3) = 1\) Underflow (8)
\((100)_2\) \((110)_2\) \((010)_2\) \((100x)_2\) \(-4 + (-2) = 2\) Underflow (9)
\((100)_2\) \((111)_2\) \((011)_2\) \((100x)_2\) \(-4 + (-1) = 3\) Underflow (10)
             
\((101)_2\) \((000)_2\) \((101)_2\) \((000x)_2\) \(-3 + 0 = -3\)    
\((101)_2\) \((001)_2\) \((110)_2\) \((001x)_2\) \(-3 + 1 = -2\)    
\((101)_2\) \((010)_2\) \((111)_2\) \((000x)_2\) \(-3 + 2 = -1\)    
\((101)_2\) \((011)_2\) \((000)_2\) \((111x)_2\) \(-3 + 3 = 0\)    
\((101)_2\) \((100)_2\) \((001)_2\) \((100x)_2\) \(-3 + (-4) = 1\) Underflow (11)
\((101)_2\) \((101)_2\) \((010)_2\) \((101x)_2\) \(-3 + (-3) = 2\) Underflow (12)
\((101)_2\) \((110)_2\) \((011)_2\) \((100x)_2\) \(-3 + (-2) = 3\) Underflow (13)
\((101)_2\) \((111)_2\) \((100)_2\) \((111x)_2\) \(-3 + (-1) = -4\)    
             
\((110)_2\) \((000)_2\) \((110)_2\) \((000x)_2\) \(-2 + 0 = -2\)    
\((110)_2\) \((001)_2\) \((111)_2\) \((000x)_2\) \(-2 + 1 = -1\)    
\((110)_2\) \((010)_2\) \((000)_2\) \((110x)_2\) \(-2 + 2 = 0\)    
\((110)_2\) \((011)_2\) \((001)_2\) \((110x)_2\) \(-2 + 3 = 1\)    
\((110)_2\) \((100)_2\) \((010)_2\) \((100x)_2\) \(-2 + (-4) = 2\) Underflow (14)
\((110)_2\) \((101)_2\) \((011)_2\) \((100x)_2\) \(-2 + (-3) = 3\) Underflow (15)
\((110)_2\) \((110)_2\) \((100)_2\) \((110x)_2\) \(-2 + (-2) = -4\)    
\((110)_2\) \((111)_2\) \((101)_2\) \((110x)_2\) \(-2 + (-1) = -3\)    
             
\((111)_2\) \((000)_2\) \((111)_2\) \((000x)_2\) \(-1 + 0 = -1\)    
\((111)_2\) \((001)_2\) \((000)_2\) \((111x)_2\) \(-1 + 1 = 0\)    
\((111)_2\) \((010)_2\) \((001)_2\) \((110x)_2\) \(-1 + 2 = 1\)    
\((111)_2\) \((011)_2\) \((010)_2\) \((111x)_2\) \(-1 + 3 = 2\)    
\((111)_2\) \((100)_2\) \((011)_2\) \((100x)_2\) \(-1 + (-4) = 3\) Underflow (16)
\((111)_2\) \((101)_2\) \((100)_2\) \((111x)_2\) \(-1 + (-3) = -4\)    
\((111)_2\) \((110)_2\) \((101)_2\) \((110x)_2\) \(-1 + (-2) = -3\)    
\((111)_2\) \((111)_2\) \((110)_2\) \((111x)_2\) \(-1 + (-1) = -2\)    

Notes:

5.2.1 An alternative way to determine over-/underflow

This is my own observation but maybe it has been proven true or false somewhere else.

In the expression \(N_1 + N_2 = S\) where \(N_1\), \(N_2\), and \(S\) are all in two’s complement representation:

5.3 Subtraction in two’s complement

Subtraction can be implemented by adding the negative counterpart. For example:

Tags: Tech