Zasadniczo, problem jest do podpisania rozciągają się od 32 bitów do ... nieskończonej liczby bitów, ponieważ Python ma dowolnie duże liczby całkowite. Zwykle rozszerzenie znaczników jest automatycznie wykonywane przez instrukcje procesora podczas rzutowania, więc interesujące jest to, że jest to trudniejsze w Pythonie, niż byłoby to na przykład, powiedzmy, C.
Podczas zabawy znalazłem coś podobnego do funkcji BreizhGatcha, ale to nie wymaga instrukcji warunkowej. n & 0x80000000
wyodrębnia 32-bitowy bit znaku; następnie -
zachowuje tę samą 32-bitową reprezentację, ale znak - rozszerza ją; w końcu bity rozszerzonych znaków są ustawione na n
.
def toSigned32(n):
n = n & 0xffffffff
return n | (-(n & 0x80000000))
Bit Twiddling Hacks sugeruje inne rozwiązanie, które być może działa bardziej ogólnie. n^0x80000000
odwraca 32-bitowy bit znaku; następnie - 0x80000000
zapisze w znaku-przedłużenie przeciwnego bitu. Innym sposobem myślenia o tym jest to, że początkowo liczby ujemne są powyżej liczb dodatnich (oddzielone przez 0x80000000
); ^
zamienia swoje pozycje; potem -
zmiany liczb ujemnych poniżej 0.
def toSigned32(n):
n = n & 0xffffffff
return (n^0x80000000) - 0x80000000
To nie jest dokładne: wszystkie obliczenia, które pasują do słowa maszyny, są wykonywane na tym poziomie. Na przykład ~ 1 == -2. Poszukuję więc sposobu na wymuszenie wyniku na typ int (co nie jest zgodne z tym, co int() najwyraźniej). –
~ 1 == -2 w języku Python na * wszystkich * systemach. Jeśli tak nie jest w systemie natywnym, to implementacja Pythona musi je emulować. (Zobacz http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy.) Jedyny przypadek, w którym natywna wielkość słowa może przeniknąć do Pythona, występuje wtedy, gdy rozmiar int jest większy niż 32-bity , co oznacza, że robisz transtion z int na długo później. –
Nie można zmusić Pythona do konwersji długich na int, gdy wartość nie mieści się w int; nie możesz pisać kodu Pythona tak, jakbyś był w C.Jeśli chcesz przekonwertować niepodpisaną 32-bitową wartość int 0xFFFFFFFF do 32-bitowej liczby całkowitej ze znakiem, reprezentowanej przez ten sam ciąg bitów, to dałem ci kod. W przeciwnym razie nie jestem pewien, co próbujesz zrobić. –