Bit field specialization in python

2019-07-29 03:33发布

Here is a code in C++:

void sign_extending(int x)
{
  int r; // resulting sign extended number goes here
  struct {signed int x:5 ;} s;
  r = s.x = x;
  cout << r; 
}

void Run()
{
  int x=29; // this 29 is -3 ( 11101 ) in 5 bits 
  // convert this from using 5 bits to a full int
  sign_extending(x);
}

The output of this code is -3. When i try to reproduce this code in python the bit field of 11101 is generated but when the answer is converted to an int the answer of 29 is given .

the following is code of python:

from bitarray import *

def sign_extending(x) :
  s = bitarray(5)
  r = s = bin(x)  #resulting sign extended number goes in r
  print (int(r, 2))

x = 29 #this 29 is -3 ( 11101 ) in 5 bits. Convert this from using 5 bits to a full int
sign_extending(x)

I also used ctypes structures as an alternative code but no use :

from ctypes import *
def sign_extending(x, b):
  class s(Structure):
      _fields_ = [("x", c_int, 5)]
  r = s.x = x
  return r  #resulting sign extended number goes in r

x = 29; #this 29 is -3 ( 11101 ) in 5 bits. 
r = sign_extending(x, 5) #Convert this from using 5 bits to a full int
print r

My question is that how would i produce this result using bit arrays or any other method that gives the correct answer.

2条回答
孤傲高冷的网名
2楼-- · 2019-07-29 03:51

In your code s is a class and the class x member actually represents the field type, so assigning s.x = 29 essentially destroys that object and assigns a normal Python int to it. Example:

>>> from ctypes import *
>>> class S(Structure):
...     _fields_ = [('x',c_int,5)]
... 
>>> S.x
<Field type=c_long, ofs=0:0, bits=5>
>>> S.x = 29
>>> S.x
29

Also, even if you create an instance first, r = s.x = 29 does not do s.x = 29 then r = s.x as in C/C++ but essentially r=29 and s.x=29. Example:

>>> from ctypes import *
>>> class S(Structure):
...     _fields_ = [('x',c_int,5)]
...     
>>> s=S()
>>> r=s.x=29
>>> s.x
-3
>>> r
29

So to fix, instantiate the class, assign s.x = 29 and return it:

from ctypes import *
def sign_extending(x, b):
    class S(Structure):
        _fields_ = [("x", c_int, b)]
  s=S()
  s.x = x
  return s.x

x = 29; #this 29 is -3 ( 11101 ) in 5 bits. 
r = sign_extending(x, 5) #Convert this from using 5 bits to a full int
print r

Output:

-3
查看更多
Anthone
3楼-- · 2019-07-29 03:52

I think that this might possibly do what you want (as long as x is non-negative and can be written using b bits).

def sign_extend(x, b):
    if x >= 2 ** (b - 1):
        return x - 2 ** b
    else:
        return x
查看更多
登录 后发表回答