2012-08-29 45 views
8

Entonces, tengo un número entero con un valor 7. (0b00000111) Y me gustaría reemplazarlo con una función a 13. (0b00001101) ¿Cuál es el mejor algoritmo para reemplazar bytes en un número entero? Por ejemplo:Modificar bits en un entero en Python

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

Al igual que en C. http://wiki.python.org/moin/BitwiseOperators – Kos

+2

Tenga cuidado con sus prefijos para enteros literales ... '0x' es el prefijo para los números _hexadecimal_. El prefijo que quieres es '0b'. –

Respuesta

3

Puede usar operaciones a nivel de bit. http://wiki.python.org/moin/BitwiseOperators

si desea establecer un bit determinado a 1 se puede utilizar en modo bit 'o' con 1 en la posición dada:

0b00000111 | 0b00001000 = 0b00001111

para establecer un bit dado a 0 se puede utilizar en modo bit 'y'

0b00001111 & 0b11111011 = 0b00001101

Tenga en cuenta que 0b prefijo es para los números binarios y 0x es para hexadecimal .

+0

Hola, en vez de publicar una nueva respuesta y eliminar la anterior, considera la posibilidad de editar tu respuesta anterior. :-) – sloth

+0

Esa era mi intención, pero la abrí en dos pestañas y la envié desde la incorrecta :) – wmiel

+0

Pero me gustaría establecer los bytes por índice. –

18

Sólo se necesita:

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 

Tenga en cuenta que los números se mordió (index) son de 0, donde 0 es el bit menos significativo.

También tenga en cuenta que el nuevo valor es devuelto, no hay forma de modificar un entero "en su lugar" como se muestra (al menos no lo creo).

+0

Dijo, casualmente, como si miles de personas inexpertas con binarios no tuvieran que seguir este código paso a paso a lo largo de los años para darse cuenta de qué demonios estaba haciendo que funcionaran tan perfectamente. – Aerovistae

+0

@Aerovistae Heh ... No estoy seguro si estás siendo irónico. Agregué comentarios para hacer que el código sea aún más claro. Con suerte eso salvará a todas esas personas un poco de trabajo. :) – unwind

+0

Gracias! De hecho, estaba siendo irónico. Tuve que volver a aprender totalmente mis operaciones binarias para entender lo que estaba pasando; no los había tocado desde la universidad. – Aerovistae

16

Estos trabajan para los enteros de cualquier tamaño, incluso superior a 32 bits:

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

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

Si te gusta las cosas a corto, sólo se puede utilizar:

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

Impresionante para configurar y borrar banderas en un entero! Ninguna biblioteca requiere :) –

Cuestiones relacionadas