2012-08-29 11 views
8

Mam więc liczbę całkowitą o wartości 7. (0b00000111) I chciałbym zastąpić ją funkcją 13. (0b00001101) Więc jaki jest najlepszy algorytm do zamiany bajtów w Liczba całkowita? Na przykład:Modyfikuj bity w liczbie całkowitej w Pythonie

set_bits(somevalue, 3, 1) # What makes the 3rd bit to 1 in somevalue? 
+1

Podobnie jak w C. http://wiki.python.org/moin/BitwiseOperators – Kos

+2

Uważaj na swoje prefiksy dla literalnych liczb całkowitych ... '0x' jest prefiksem dla liczb _hexadecimal_. Prefiks, którego chcesz, to '0b'. –

Odpowiedz

3

Można użyć operacji bitowych. http://wiki.python.org/moin/BitwiseOperators

jeśli chcesz ustawić daną bitu na 1 można użyć bitowego „lub” z 1 na danym stanowisku:

0b00000111 | 0b00001000 = 0b00001111

ustawić dany bit na 0 można użyć bitowego 'i'

0b00001111 & 0b11111011 = 0b00001101

Zauważ, że 0b prefix jest dla liczb binarnych i 0x jest szesnastkowym .

+0

Cześć, zamiast zamieszczać nową odpowiedź i usuwać starą, rozważ edytowanie starej odpowiedzi. :-) – sloth

+0

To była moja intencja, ale otworzyłem ją w dwóch zakładkach i wysłałem z niewłaściwego :) – wmiel

+0

Ale chciałbym ustawić bajty według indeksu. –

18

Wystarczy:

def set_bit(v, index, x): 
    """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new value.""" 
    mask = 1 << index # Compute mask, an integer with just bit 'index' set. 
    v &= ~mask   # Clear the bit indicated by the mask (if x is False) 
    if x: 
    v |= mask   # If x was True, set the bit indicated by the mask. 
    return v   # Return the result, we're done. 

>>> set_bit(7, 3, 1) 
15 
>>> set_bit(set_bit(7, 1, 0), 3, 1) 
13 

Należy zauważyć, że nieco liczb (index) wynosi od 0, z 0 jest najmniej znaczący bit.

Zauważ również, że nowa wartość to zwróciła, nie ma możliwości zmodyfikowania liczby całkowitej "na miejscu", tak jak pokazujesz (przynajmniej nie sądzę).

+0

Powiedział od niechcenia, jakby tysiące ludzi niedoświadczonych binarnie nie musieliby przechodzić przez ten kod krok po kroku przez lata, aby dowiedzieć się, co to do cholery było, co sprawiło, że działa tak doskonale. – Aerovistae

+0

@Aerovistae Heh ... Nie jestem pewien, czy jesteś zuchwały. Dodałem komentarze, aby uczynić kod jeszcze jaśniejszym. Mam nadzieję, że uratuje to wszystkich tych ludzi, którzy pracują. :) – unwind

+0

Dzięki! Rzeczywiście byłem zuchwały. Musiałem całkowicie odnowić moje binarne operacje, aby zrozumieć, co się dzieje; nie tknął ich od czasów college'u. – Aerovistae

16

Działają one dla liczb o dowolnych rozmiarach, nawet większy niż 32 bitowe:

def set_bit(value, bit): 
    return value | (1<<bit) 

def clear_bit(value, bit): 
    return value & ~(1<<bit) 

Jeśli lubisz rzeczy krótki, można po prostu użyć:

>>> val = 0b111 
>>> val |= (1<<3) 
>>> '{:b}'.format(val) 
'1111' 
>>> val &=~ (1<<1) 
'1101' 
+0

Niesamowite przy ustawianiu i czyszczeniu flag w liczbie całkowitej! Żadne biblioteki nie wymagają :) –

Powiązane problemy