Read 32-bit signed value from unsigned stream

I want to extract data from a file that stores information in big-endian and always unsigned. How does cast from unsigned int to int affect the actual decimal value? Is it right that the leftmost bit determines whether the value is positive or negative?

I want to parse this file format with python, and reading and an unsigned value is easy:

def toU32(bits): return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8 | ord(bits[3]) 

but what would the corresponding s32 function look like?


Thanks for the info on the struct module. But I'm still interested in resolving my current issue.

+4
source share
3 answers

I would use a struct .

 import struct def toU32(bits): return struct.unpack_from(">I", bits)[0] def toS32(bits): return struct.unpack_from(">i", bits)[0] 

The format string "> I" means reading the large end, ">", unsigned integer, "I" from the string bits. For signed integers, you can use "> i".

EDIT

Had to look at another StackOverflow answer to remember how to "convert" a signed integer from an unsigned integer in python. Although this is less conversion and more reinterpretation of bits.

 import struct def toU32(bits): return ord(bits[0]) << 24 | ord(bits[1]) << 16 | ord(bits[2]) << 8 | ord(bits[3]) def toS32(bits): candidate = toU32(bits); if (candidate >> 31): # is the sign bit set? return (-0x80000000 + (candidate & 0x7fffffff)) # "cast" it to signed return candidate for x in range(-5,5): bits = struct.pack(">i", x) print toU32(bits) print toS32(bits) 
+8
source

The non-conditional version of toS32 (bit) could be something like this:

 def toS32(bits): decoded = toU32(bits) return -(decoded & 0x80000000) + (decoded & 0x7fffffff) 

You can also pre-compute the mask for any other bit size.

0
source

Source: https://habr.com/ru/post/1395648/


All Articles