2016-08-05 32 views
1

Hier ist ein Code in C++:Bitfeld Spezialisierung in Python

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

Der Ausgang dieses Codes ist -3. Wenn ich versuche, diesen Code in Python zu reproduzieren, wird das Bitfeld von 11101 erzeugt, aber wenn die Antwort in ein int umgewandelt wird, wird die Antwort von 29 gegeben.

das Folgende Code von 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 ctypes Strukturen als Alternative Code, aber keine Verwendung auch verwendet:

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 

Meine Frage ist, wie kann ich das Ergebnis mit wenig produzieren Arrays oder jede andere Methode, die die richtige Antwort gibt.

Antwort

2

In Ihrem Code s ist eine Klasse und die Klasse x Mitglied stellt tatsächlich den Typ-Feld, zerstört so die Zuordnung s.x = 29 im Wesentlichen das Objekt und weist einen normalen Python int zu. Beispiel:

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

Auch wenn Sie eine Instanz zunächst erstellen, r = s.x = 29 nicht tun s.x = 29 dann r = s.x wie in C/C++, aber im Wesentlichen r=29 und s.x=29. Beispiel:

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

So um die Klasse zu beheben, instanziiert, weisen s.x = 29 und senden Sie es:

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 

Ausgang:

-3 
+0

danke für die antwort ich werde es als richtig markieren. Auch nur aus Neugier, wie würde ich das Gleiche mit Bitarrays tun? –

1

Ich denke, dass dies möglicherweise tun könnte, was Sie wollen (solange x nicht negativ ist und mit b Bits geschrieben werden kann).

def sign_extend(x, b): 
    if x >= 2 ** (b - 1): 
     return x - 2 ** b 
    else: 
     return x 
+0

Ihre Antwort ist richtig, aber ich hatte gehofft, eine Lösung zu erhalten durch Verwendung des Bitarrays oder des Strukturcodes. Da es sinnvoller wäre, Bitfelder wie im C++ - Code –

+1

angegeben zu verwenden, ist zu beachten, dass "1 << n" _much_ schneller ist als "2 ** n". –