Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guaranteeing negative result when left shifting a negative number in two's complement?

Assuming a negative binary number is represented in two's complement, how can we guarantee the sign is preserved?

Let's say we represent a decimal number -5 in four bits: 1011, and want to left-shift one place to multiply by 2:

1011 << 1

This operation returns 0110, which is 6, not -10 as we would have hoped.

(I assume this is only the case for negative numbers whose second bit is 0, ie negative numbers close to the smallest representable negative number of some range)

like image 552
sgarza62 Avatar asked Oct 06 '14 20:10

sgarza62


People also ask

How do you represent negative numbers in 2s complement?

Negating a two's complement number is simple: Invert all the bits and add one to the result. For example, negating 1111, we get 0000 + 1 = 1. Therefore, 1111 in binary must represent −1 in decimal.

Why is 2s complement used to store negative numbers?

Two's complement allows negative and positive numbers to be added together without any special logic. This means that subtraction and addition of both positive and negative numbers can all be done by the same circuit in the cpu. ... Adding is the same mechanism as plain positive integers adding.

Is 2s complement only for negative number?

Two's complement notation includes both positive and negative numbers.


1 Answers

OP here. I found the answer to my question.

Shifting left may trigger arithmetic overflow.

The range of numbers expressible by a two's complement system is from -(2^(n-1)) to 2^(n-1)-1, where n is the number of bits available, including the sign bit (MSB). So, in the above example where each number uses 4 bits, the range of possible values is -8 to 7, inclusive.

Shifting left by m bits will multiply the number by 2^m. So, in the above example -5 << 1 would yield -10, which is beyond the range of possible numbers in a 4-bit signed representation – that's an overflow.

1111 << 1 == 1110 // -1 * 2 is -2
1110 << 1 == 1100 // -2 * 2 is -4
1101 << 1 == 1010 // -3 * 2 is -6
1100 << 1 == 1000 // -4 * 2 is -8
1011 << 1 == 0110 // overflow
1010 << 1 == 0100 // overflow
1001 << 1 == 0010 // overflow
1000 << 1 == 0000 // overflow

In conclusion, while using ASL to multiply by powers of two, it is important to make sure the product lies within the range of possible values.

like image 68
sgarza62 Avatar answered Oct 13 '22 11:10

sgarza62