Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two's complement of Hex number in Python

Below a and b (hex), representing two's complement signed binary numbers. For example:

a = 0x17c7cc6e
b = 0xc158a854

Now I want to know the signed representation of a & b in base 10. Sorry I'm a low level programmer and new to python; feel very stupid for asking this. I don't care about additional library's but the answer should be simple and straight forward. Background: a & b are extracted data from a UDP packet. I have no control over the format. So please don't give me an answer that would assume I can change the format of those varibles before hand.

I have converted a & b into the following with this:

aBinary = bin(int(a, 16))[2:].zfill(32) => 00010111110001111100110001101110 => 398969966
bBinary = bin(int(b, 16))[2:].zfill(32) => 11000001010110001010100001010100 => -1051154348

I was trying to do something like this (doesn't work):

if aBinary[1:2] == 1:
aBinary = ~aBinary + int(1, 2)

What is the proper way to do this in python?

like image 790
Nimjox Avatar asked Oct 29 '14 22:10

Nimjox


2 Answers

why not using ctypes ?

>>> import ctypes
>>> a = 0x17c7cc6e
>>> ctypes.c_int32(a).value
398969966
>>> b = 0xc158a854
>>> ctypes.c_int32(b).value
-1051154348
like image 74
Roman Avatar answered Sep 19 '22 12:09

Roman


A nice way to do this in Python is using bitwise operations. For example, for 32-bit values:

def s32(value):
    return -(value & 0x80000000) | (value & 0x7fffffff)

Applying this to your values:

>>> s32(a)
398969966
>>> s32(b)
-1051154348

What this function does is sign-extend the value so it's correctly interpreted with the right sign and value.

Python is a bit tricky in that it uses arbitrary precision integers, so negative numbers are treated as if there were an infinite series of leading 1 bits. For example:

>>> bin(-42 & 0xff)
'0b11010110'
>>> bin(-42 & 0xffff)
'0b1111111111010110'
>>> bin(-42 & 0xffffffff)
'0b11111111111111111111111111010110'
like image 34
dcoles Avatar answered Sep 18 '22 12:09

dcoles