2

这是 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);
}

此代码的输出为 -3。当我尝试在 python 中重现此代码时,会生成 11101 的位字段,但是当答案转换为 int 时,会给出 29 的答案。

以下是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)

我还使用 ctypes 结构作为替代代码,但没有用:

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

我的问题是,我将如何使用位数组或任何其他给出正确答案的方法来产生这个结果。

4

2 回答 2

2

在您的代码s中是一个类,而类x成员实际上代表字段类型,因此分配s.x = 29本质上会破坏该对象并为其分配一个普通的 Python int。例子:

>>> 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

此外,即使您首先创建一个实例,r = s.x = 29也不会像在 C/C++ 中那样做s.x = 29r = s.x而是在本质上r=29s.x=29. 例子:

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

所以要修复,实例化类,分配s.x = 29并返回它:

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

输出:

-3
于 2016-08-06T02:05:49.007 回答
1

我认为这可能会做你想要的(只要 x 是非负数并且可以使用 b 位写入)。

def sign_extend(x, b):
    if x >= 2 ** (b - 1):
        return x - 2 ** b
    else:
        return x
于 2016-08-05T18:00:14.253 回答