2

I am struggeling to convert a byte array (bytes) back to a singed integer. I found a lot of examples which are valid for having positive integers after the conversion but no working example how to handle a negative number.

#example for positive numbers is working fine    
data = I2C.read_i2c_block_data(I2CAddress, I2CRegister, 4)

result = 0

for b in data:
    result = result * 256 + int(b)

I am running python on a raspberry with python version 2.7.9.

It would be nice to get a basic algorithm for that.

My goal is to convert the byte array from variable data back to a negative number.

variable data has these items in its array:

[0xff, 0xff, 0xff, 0xe7]

Target negative number is -25 (which is obviously 0xe7)

Cheers

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
d s
  • 237
  • 1
  • 2
  • 11
  • 1
    Can you provide an example for `data` and what you expect `result` to be at the end? – Code-Apprentice Dec 04 '19 at 23:46
  • #example for positive numbers is working fine data = I2C.read_i2c_block_data(I2CAddress, I2CRegister, 4) result = 0 for b in data: result = result * 256 + int(b) an arduino is sending a negative integer as a byte array over I2C. In data variable the array looks like: 0xff 0xff 0xff 0xe7 this is the representation of -25 integer as a byte array. So how can i convert that back using basic algorithm or existing methods which are supported in python 2.7.9 – d s Dec 04 '19 at 23:48
  • Side note: when manipulating binary data, we typically use binary operators like `<<`, `&` and `|` instead of arithmetic operators like `*` and `+`. Changing to these won't necessarily solve your current problem, but it is good to learn how to use these operators. – Code-Apprentice Dec 04 '19 at 23:48
  • 1
    Side-note: Migrating to Python 3 would make this *much* simpler and *much* more efficient, thanks to [the `int.from_bytes` alternate constructor](https://docs.python.org/3/library/stdtypes.html#int.from_bytes) (which can interpret as signed or unsigned values). – ShadowRanger Dec 05 '19 at 00:07
  • Also note: If the bytes in question are encoded C type `int`s, the `struct` module is the way to handle this, e.g. `struct.unpack('>i', bytearray([0xff, 0xff, 0xff, 0xe7]))[0]` – ShadowRanger Dec 05 '19 at 00:09

1 Answers1

2

Once you find the unsigned result using the above method, you can convert it to a signed integer:

max_int = 2**(8*len(data)-1)-1
result = result - (2 * (max_int + 1) if result > max_int else 0)
Selcuk
  • 57,004
  • 12
  • 102
  • 110