Convert signed binary data to integer

I read the binary and get an array with characters. When converting two bytes to an integer, I do 256*ord(p1) + ord(p0) . It works fine for positive integers, but when I get a negative number, it doesn't work. I know that there is something with the first bit in the most significant byte, but without success.

I also understand that there is something called struct , and after reading it I got the following code

 import struct p1 = chr(231) p0 = chr(174) a = struct.unpack('h',p0+p1) print str(a) 

a becomes -6226, and if I exchange p0 and p1 , I get -20761.

a should be -2

+4
source share
6 answers

Typically, when using struct, your format string should begin with one of the alignment specifiers . By default, native is different from machine to machine.

Therefore, the correct result

 >>> struct.unpack('!h',p0+p1)[0] -20761 

Representation -2 in large endian :

 1111 1111 1111 1110 # binary 255 254 # decimal bytes fffe # hexadecimal bytes 

You can easily make sure that adding two leads to 0.

+1
source

-2 is incorrect for the values ​​you specify, and byte order matters. struct uses > for big-endian (highest byte first) and < for low byte (low byte):

 >>> import struct >>> struct.pack('>h',-2) '\xff\xfe' >>> struct.pack('<h',-2) '\xfe\xff' >>> p1=chr(254) # 0xFE >>> p0=chr(255) # 0xFF >>> struct.unpack('<h',p1+p0)[0] -2 >>> struct.unpack('>h',p0+p1)[0] -2 
+1
source

Using the first method ( 256*ord(p1) + ord(p0) ) you can check if the first bit matches 1 with if p1 & 0x80 > 0 . If so, you should use p1 & 0x7f instead of p1 , and then negate the end result.

0
source

Your original equation will work fine if you use disguise to remove extra bits 1 in a negative number:

 256*(ord(p0) & 0xff) + (ord(p1) & 0xff) 

Edit: I think I may have misunderstood your question. Are you trying to convert two positive byte values ​​to a negative integer? This should work:

 a = 256*ord(p0) + ord(p1) if a > 32767: # 0x7fff a -= 65536 # 0x10000 
0
source

For the record, you can do this without a struct . Your original equation can be used, but if the result is greater than 32767, subtract 65536. (Or if the high byte is greater than 127, this is one and the same.) Look at the two additions, as all modern computers represent negative integers.

 p1 = chr(231) p0 = chr(174) a = 256 * ord(p1) + ord(p0) - (65536 if ord(p1) > 127 else 0) 

This gives you the correct answer -6226. (The correct answer is not -2.)

0
source

If you are converting values ​​from a large file, use the array module.

For a file, be aware that this is the end of the file format. Not the specification of a machine that either wrote or read it.

Alex Martelli, of course, has the final answer .

0
source

All Articles