python 中的位域专业化
Bit field specialization in python
这是 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
我的问题是如何使用位数组或任何其他给出正确答案的方法生成此结果。
我认为这可能会做你想要的(只要 x 是非负的并且可以用 b 位来写)。
def sign_extend(x, b):
if x >= 2 ** (b - 1):
return x - 2 ** b
else:
return x
在您的代码中 s
是一个 class 并且 class 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 = 29
然后 r = s.x
但本质上是 r=29
和 s.x=29
。示例:
>>> from ctypes import *
>>> class S(Structure):
... _fields_ = [('x',c_int,5)]
...
>>> s=S()
>>> r=s.x=29
>>> s.x
-3
>>> r
29
所以要修复,实例化 class,分配 s.x = 29
和 return 它:
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
这是 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
我的问题是如何使用位数组或任何其他给出正确答案的方法生成此结果。
我认为这可能会做你想要的(只要 x 是非负的并且可以用 b 位来写)。
def sign_extend(x, b):
if x >= 2 ** (b - 1):
return x - 2 ** b
else:
return x
在您的代码中 s
是一个 class 并且 class 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 = 29
然后 r = s.x
但本质上是 r=29
和 s.x=29
。示例:
>>> from ctypes import *
>>> class S(Structure):
... _fields_ = [('x',c_int,5)]
...
>>> s=S()
>>> r=s.x=29
>>> s.x
-3
>>> r
29
所以要修复,实例化 class,分配 s.x = 29
和 return 它:
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