Why do k arithmetic right/left bit shifts divide by $2^k$/multiply by $2^k$ in two's complement, rigorously?

109 Views Asked by At

I want to understand the semantics of rights bit shifts x>>k in two's complement properly, in particular why do right bit shifts of size $k$ approximately divide $x$ by $2^k$ (and ideally making this "approx" precise and also handling the arithmetic left bit shift too).

So the representation of a number in two complement is for a $N$ bit length word: $$ x = -a_{N-1} 2^{N-1} + \sum^{N-2}_{i=0} a_{i} 2^i = neg + pos $$ e.g., as a intentionally selected running example $-6$ is $1010_2$ which is $-8 + 0 + 2 + 0$. I'm thinking of bit slots [-8, 4, 2, 1] <-> [-2^3, 2^2, 2^1, 2^0] for each bit. When doing an arithmetic right bit shift we get $1101_2$ which ends up being $-3 = -8 + 4 + 0 + 1$ in twos complement.

When the most significant bit (MSB) is $0$ the mathematics seems trivial. If you move the bits to the right it's a division by two because every number is divided by two (maybe floor since we lose the final bit sometimes if it's 1). With negative numbers using 2s complement it seems more complicated. We want -6 -> -3. Intuitively I would have assumed to "double" the positive part $pos$ but that doesn't quite work and results in left shift on $pos$ anyway. So no.

I've worked out a couple (many?) examples and wrote the equations but I can't seem to figure out the pattern. Why is a right bit arithmetic where you "carry the MSB" work with the intended semantics (divide by $2^k$ or multiply by $2^k$) for both positive and negative representations of numbers?

I've read related questions but I am still confused:

2

There are 2 best solutions below

0
On

In two's complement, let the bit representation be $T=a_{N-1}\dots a_0$, with $a_{N-1}$ the most significant bit (MSB) with a value of $-2^{N-1}$, and $a_0$ as the least significant bit (LSB) with value $1$.

The numerical value of $|T|$ is the positive integer $S$ represented by $S=a_{N-2}\dots a_0$, where $T=-2^{N-1}+S$.

As $S+NOT(S)+1=2^{N-1}$, then $|T|=NOT(S)+1$, where $NOT(S)$ is the one's complement. Similarly, if $S$ is a positive integer, $-S = -2^{N-1} + NOT(S) + 1$.

So in order to halve $T$ (knowing that $T<0$) we can halve $NOT(S)+1$ by performing a logical right shift ($>>1$).

Note that the floor function has slightly unusual behaviour when changing from positive to negative odd numbers, $\lfloor \frac{5}{2}\rfloor = 2$, whereas $\lfloor \frac{-5}{2}\rfloor = -3$ for example, so converting back to two's complement needs to take this into consideration.

If $L=(NOT(S)+1)$ is odd, then $\frac{|T|}{2}=-2^{N-1} + NOT(L>>1)$, otherwise $\frac{|T|}{2}=-2^{N-1} + NOT(L>>1)+1$.

Examining the edge cases of $S=0$ and $S=2^{N-1}-1$ gives

$S=0, NOT(S)=2^{N-1}-1, NOT(S)+1=2^{N-1} (even), L>>1=2^{N-2}, NOT(L)=2^{N-2}-1$

Then $\frac{|T|}{2}=-2^{N-1} + 2^{N-2}=-2^{N-2}$ as required.

$S=2^{N-1}-1, NOT(S)=0,NOT(S)+1=1 (odd), L>>1=0, NOT(L)=2^{N-1}-1$.

Then $\frac{|T|}{2}=-2^{N-1} + 2^{N-1}-1=-1$ as required.

Note that bit $N-2$ is always set, therefore an arithmetic right shift is as defined in the literature.

0
On

Since it seems that you haven't understood how 2-complement works, I'll explain it first, then I'll explain how right shift works for 2-complement negative numbers.

How 2-complement works

Let $N$ be the number of binary digits used for storing a number. For every $n\in\mathbb{Z},N\in\mathbb{N}^+$ there exists a unique $k \in \mathbb{Z}$ and a unique finite sequence $(d_i)$, $d_i\in\{0,1\}$, $0\leq i\leq N-1$ such that $$n = 2^N k+ \sum_{i = 0}^{N-1}{2^id_i}$$ This can simply be proven inductively. Now you see that $d_i$ is the $i$-th digit of the binary system, which are stored in the memory. $k$, however, is not stored, hence it must be chosen. For unsigned integers, the choice is naturally $k = 0$, leading to

$$n = \sum_{i = 0}^{N-1}{2^id_i}$$

A consequence is that $n$ can only represented for $0 \leq n \leq 2^N-1$. For signed integers, this is clearly problematic because there isn't any negative integer at all. We also want a way to represent them in such a way that their difference from the unsigned system is minimal.

So how do we represent negative numbers? Well, the fundamental property of negative numbers is that $$a+(-a)=0$$

Now, let $\bar{a} = 2^N - a$, we have that: $$a + \bar{a} = 2^N = 2^N + 0$$ While $a+\bar{a} > 0$, its N binary digits are $equal$ to those of $0$. By ignoring the fact that we made an overflow ($k$ increased by $1$), we made $b$ equavilent to $-a$. But, wait for it, we can also prove it works for multiplication! $$a\bar{b} = a(2^N-b) = 2^Na + a(-b)$$ So we managed to represent negative numbers without changing how we do addition and multiplications, the two essential operations on integers! Now we need to choose the values for which the number is positive. As you have known, this is chosen via the MSB. Let $u(n)$ be the usigned number which have the same digits as signed integer $n$, then that means: $$ \begin{align} &&&\begin{cases} u(n) = n, &0\leq u(n) \leq 2^{N-1}-1\\[10pt] u(n) = n+2^N, &2^{N-1} \leq u(n) < 2^N\\ \end{cases}\\[10pt] &\Leftrightarrow&&\begin{cases} u(n) = n, &0 \leq n \leq 2^{N-1}-1\\[10pt] u(n) = n+2^N, &2^{N-1} \leq n < 0\\ \end{cases} \end{align} $$ consequently, the range of values is $-2^{N-1}\leq n \leq 2^{N-1}-1$. Additionally, exactly half of them are positive (perfectly balanced, as all things should be) and they can be easily extended to higher number of digits by repeating the MSB (try to prove that yourself) :)

Well we got the digits for negative numbers, now we need a way to calculate them on a circuit. Notice that: $$\begin{align}\bar{n} = 2^N - n &= 1+ (2^N-1)-n\\ &= 1 + \sum_{i = 0}^{N-1}2^i - \sum_{i = 0}^{N-1}{2^id_i}\\ &= 1 + \sum_{i = 0}^{N-1}{2^i(1-d_i)}\\ \end{align} $$ It's clear that $\sum_{i = 0}^{N-1}{2^i(1-d_i)}$ is the 1-complement of $n$, which is easy to do by flipping every bit. Then we just need to add 1. This is where the 2-complement thing comes from. Now we are ready to learn how right shift works

How right-shift works

Let $m$ be the result of shifting $n$ by $1$ digit to the right. For $n>0$, we have $$m = \sum_{i = 1}^{N-1}{2^{i-1}d_{i}}$$ Hence$$ 2m = \sum_{i = 1}^{N-1}{2^id_{i}} = n-d_0$$ Clearly, $m$ is approximately half of $n$.

For $n < 0$, we have:

$$u(m) = 2^{N-1} + \sum_{i = 1}^{N-1}{2^{i-1}}d_{i}$$ Where $u(m)$ is the unsigned counterpart of $m$. The $2^{N-1}$ term is there because we carried the MSB, which is $1$. Consequently $$m = u(m) - 2^N = \sum_{i = 1}^{N-1}{2^{i-1}d_i} - 2^{N-1}$$ Hence $$2m = \sum_{i = 1}^{N-1}{2^id_{i}} - 2^{N} = n - d_0$$ Thus $m$ is also nearly half of $n$ for $n<0$