2012-07-21 17 views
5

estoy tratando de hacer lo siguiente:Bits de configuración en C

Escribe un func setbits(x,p.n,y) que devuelve x con n bits que comienzan en la posición p conjunto de los bits de la derecha de ny, dejando el otro los bits sin cambios?

Lo intenté así pero no recibí las respuestas correctas. ¿Alguien puede decir dónde estoy equivocado?

unsigned setbits(unsigned x,int p,int n,unsigned y) 
{ 
    return (x>>p & (y|(~0<<n))); 
} 
+1

En primer lugar, cuando escribe C bit a bit, es una gran idea usar variables temporales con nombres útiles para ayudarlo a ver lo que está haciendo. El compilador probablemente los optimizará de todos modos, pero la legibilidad del código fuente permanecerá. – Misha

+0

he editado la función para tomar x un parámetro s. – user1413523

+0

x es actualmente una variable de 1 bit de ancho, y al cambiarlo por cualquier p, se pondrá a cero. – Misha

Respuesta

1

Kernighan and Ritchie, 2nd edition, exercise 2-6. La solución es de http://users.powernet.co.uk/eton/kandr2/krx206.html:

(x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n))

+0

No sé si mis ojos o mi cerebro duelen más. De cualquier manera, +1: p – Corbin

+1

Pobre bastardo que tiene que mantener esto: D – RedX

+0

-1 para copiar y pegar sin agregar nada (debería ser un comentario), y para una respuesta que es inútil incluso si funciona. – Potatoswatter

3

Algo así como:

unsigned setbits(unsigned x,int p,int n,unsigned y) 
{ 
    unsigned mask = (1U << n) - 1U; // n-bits 
    y &= mask; // rightmost n bits of y 
    y <<= p; // which begin at position p 
    mask <<= p; //idem 
    x &= ~mask; //set the 0s 
    x |= y;  //set the 1s 
    return x; 
} 

O si desea hacerlo en un menor número de líneas, más difíciles de depurar, pero muuuucho más frías:

unsigned setbits(unsigned x,int p,int n,unsigned y) 
{ 
    unsigned mask = (1U << n) - 1U; // n-bits 
    return (x & ~(mask << p)) | ((y & mask) << p); 
} 
+0

@Potatoswatter: estoy corregido. – rodrigo

1

Capturando los últimos n bits de y: (será un número con los últimos n bits iguales a y, y los demás configurados a cero)

last_n_bits_of_y = y & (((1<<(n+1))-1); 

entonces podemos compensarlo por (32-n-p + 1) (mira esto!)

last_n_bits_of_y_offset = last_n_bits_of_y << (32-n-p+1); 

ahora que borrar los bits de x queremos cambiar:

new_x = x & (~((((1<<(n+1))-1) << (32-n-p+1))); 

y rellenarla con nuestros pedacitos:

new_x = new_x & last_n_bits_of_y_offset; 

eso es todo! Realmente no lo probé, pero con suerte, entenderás la idea.

+1

Los tres de sus '&&' probablemente sean '&' – Oleg2718281828

+0

Ops, gracias. Fijo. –

1
  1. You x>>() por lo que sueltas x bits de la derecha y luego nunca restaurarlos posteriormente en funcionas.
  2. No se puede activar bits usando sólo & ya que el resultado depende de los dos operandos a menos que sepa uno de ellos consiste sólo en 1
  3. (y|(~0<<n)) se supone que cortar trozos de y pero no lo es, esta vez | no es la correcta herramienta, use & y el segundo operando apropiado.

Aquí está la solución (apuesto hay más corta, pero esto es recta de avance):

(x & ~(~(~0<<n)<<p) | (y&~(~0<<n)) << p); 

Parte izquierda de | despeja el lugar en x (n bits en la posición p) y la parte derecha trae y bits.

Cuestiones relacionadas