-1

I have an array of (short) data which is shifted 4 to left and it is also a signed number. I need to plot it around zero.

for instance: if the number in the array is 0b0000000011111111 and I shift it to left by 4, I will get 0b000000001111. it is fine.

for instance: if the number in the array is 0b100011111111 and I shift it to left by 4, I will get 0b000010001111. It is fine, but now it is not a negative number.

can someone help ?

toti08
  • 2,448
  • 5
  • 24
  • 36
  • 2
    Your question is not clear. In both instances, you say "shift it to left" but it looks like a shift to the *right* (toward the least significant bit). Do you mean "shift it to the right"? Also, the problem itself is not clear. Do you want to shift negative numbers and still get a negative number? Also, just how do you do the shifts? What is the data format of the numbers--16 bit integers? What kind of variable is it in? – Rory Daulton Aug 08 '18 at 07:24
  • The only solution I can think of is to convert them to positive numbers before making the shift and then back to negative. [This wikipedia page](https://en.wikipedia.org/wiki/Two's_complement) provides a good explanation of how two's compliment works. – Bill Aug 08 '18 at 07:25
  • 1
    Python doesn't use two's complement in its integers, `0b10001111111 == 2303`. – jonrsharpe Aug 08 '18 at 07:25
  • @ jonrsharpe FYI you're missing a `1` at the end (`0b100011111111`). – Bill Aug 08 '18 at 07:28

3 Answers3

1

You have to write your own implementation of the arithmetic right shift of a 16-bit value, if this is what you need. I suggest you this one, very easy to understand:

def arithmetic_right_shift_on_16_bits(val, n):
    # Get the sign bit
    s = val & 0x8000
    # Perform the shifts, padding with the sign bit
    for _ in range(n):
        val >>= 1
        val |= s
    return val

a = arithmetic_right_shift_on_16_bits(0b0000000011111111, 4)
print(bin(a)) # 0b1111

b = arithmetic_right_shift_on_16_bits(0b1000000011111111, 4)
print(bin(b)) # 0b1111100000001111
Laurent H.
  • 6,316
  • 1
  • 18
  • 40
0

This does not happen in Python:

>>> bin(0b0000000011111111 >> 4)  # 15
'0b1111'
>>> bin(0b100011111111 >> 4)  # 143
'0b10001111'
L3viathan
  • 26,748
  • 2
  • 58
  • 81
0

BTW, the number you show as an example of a negative short integer is not one, because you gave only 12 bits. So I will assume that the number of interest is 0b1000000011111111. As Python does not use 2's complement, it is shown as 33023. But you can do the 2's complement by hand: for a short int (16 bits), you just substract 0x10000 to the number.

You can then write:

def short_signed_right_shift(x, i):
    if x < 0 or x >= 0x10000: raise ValueError   # only accept 16 bits numbers
    return x >> i if (x < 0x7FFF) else 0x10000 + ((x - 0x10000) >> i)

You can then use it:

>>> bin(short_signed_right_shift(0b0000000011111111, 4))
'0b1111'
>>> bin(short_signed_right_shift(0b1000000011111111, 4))
'0b1111100000001111'
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252