2012-04-28 32 views
9

Tengo una serie de caracteres que estoy tratando de desplazar en bit a la derecha >>, luego & con otra matriz. Creo que tengo una idea equivocada de cómo hacer esto.Arrays de desplazamiento bit a bit

pensé, a pesar de que era un conjunto de caracteres simplemente indicando my_array >>= 1 cambiaría todo, pero estoy recibiendo un error: "error: invalid operands to binary >> (have ‘char[8]’ and ‘int’)"

La comparación bit a bit que estoy tratando de hacer es con una matriz de tamaño similar iniciada a todos "0's" ... para eso obtengo: "error: invalid operands to binary & (have ‘char *’ and ‘char *’)"

¿Debo convertir estas matrices en otra cosa antes de poder cambiar y comparar?

Disculpe, no estaba súper claro ... Todos los buenos consejos hasta este punto y creo que me estoy dando cuenta de que no hay una forma muy fácil de hacerlo. Más específicamente, lo que estoy tratando de hacer es cambiar los bits de la matriz de caracteres ENTER completamente a la derecha 1, agregando el bit desplazado de la parte posterior derecha al lado izquierdo de la matriz, hacer la comparación bit a bit con otra matriz del mismo tamaño.

Técnicamente, la comparación no tiene que ser una matriz con matriz ... Solo necesito los bits. ¿Sería más fácil convertir las matrices en otra cosa antes de intentar hacer los cambios/comparaciones?

+2

¿Está tratando de rotar el contenido de la matriz, o está tratando de desplazar en bit cada elemento individual de la matriz? Ninguna de esas operaciones existe en forma nativa en C. Tendrá que escribir un bucle que copia cada elemento en una ubicación, o mueve en forma de bit cada elemento en la matriz. – chrisaycock

Respuesta

10

usted tiene que cambiar y compara elementwise.

for(i = 0; i < len; ++i) 
    array[i] >>= 3; 

por ejemplo. Si desea mover los bits desplazados fuera de un elemento a otro, es más complicado, digamos que está desplazando a la derecha, a continuación,

unsigned char bits1 = 0, bits2 = 0; 
for(i = len-1; i >= 0; --i) { 
    bits2 = array[i] & 0x07; 
    array[i] >>= 3; 
    array[i] |= bits1 << 5; 
    bits1 = bits2; 
} 

atravesar la matriz en la otra dirección, ya que necesita los bits de la siguiente mayor espacio

2

Tendrá que cambiar las entradas en la matriz una por una. (Y si quiere comparar dos de estos, tendrá que hacerlo elemento por elemento.)

Si esperaba que los bits cambiaran, cada char se desplazaría al siguiente, necesitaría cuídalo también manualmente.

Si quieres ese comportamiento de cambiar al siguiente byte, y no te molesta hacer que tu código sea desagradable, no sea portable y propenso a errores, podrías tomar un puntero al arreglo, lanzarlo a algo como unsigned long long *, desreferenciarlo y cambiar el entero resultante, y almacenarlo de nuevo.

pero si eso es el comportamiento que desea a continuación, usted debe utilizar un número entero en lugar de un char[8] para empezar.

(si se puede decir más acerca de lo que en realidad estás con el objetivo de lograr, a continuación, las respuestas más útiles pueden ser posibles.)

2

Si desea realizar operaciones tales como cambiar/OR/XOR/AND/etc .. en matrices, debe realizarlo en un bucle, no puede realizarlo directamente en la matriz.

2

Puede cambiar solo los miembros de esas matrices, un char (o un int). No puedes cambiar una matriz completa. Al desplazar my_array se intenta realizar una operación de desplazamiento en un tipo de matriz (o un puntero a char) que es imposible.Hacer esto en su lugar:

for (i = 0; i < size; i++) { 
    my_array[i] >>= 1; 
} 

También hay que tener cuidado con los caracteres ya que suelen ser firmados, y un char que contiene un valor negativo traerá '1' de la izquierda en lugar de ceros. Entonces será mejor que uses caracteres sin firmar.

EDITAR: El código anterior es simplista. Si pretendía cambiar la matriz en conjunto, no solo cada byte, entonces debe copiar "manualmente" cada LSB al MSB del byte a su derecha. Eche un vistazo a la respuesta de Richard Pennington.

+0

Supongo que quiere tratar la matriz como un valor único, por lo que también necesitaría llevar un poco del byte más significativo. – loganfsmyth

+0

Correcto, edité mi respuesta. Gracias –

3
/** Shift an array right. 
* @param ar The array to shift. 
* @param size The number of array elements. 
* @param shift The number of bits to shift. 
*/ 
void shift_right(unsigned char *ar, int size, int shift) 
{ 
    int carry = 0;        // Clear the initial carry bit. 
    while (shift--) {       // For each bit to shift ... 
     for (int i = size - 1; i >= 0; --i) { // For each element of the array from high to low ... 
      int next = (ar[i] & 1) ? 0x80 : 0; // ... if the low bit is set, set the carry bit. 
      ar[i] = carry | (ar[i] >> 1);  // Shift the element one bit left and addthe old carry. 
      carry = next;      // Remember the old carry for next time. 
     } 
    } 
} 
+0

Bueno, esto se ve raro, o me falta algo. Parece una mezcla de desplazamiento a la derecha y desplazamiento a la izquierda. El comentario al lado del bit de acarreo dice "Mueva el elemento un bit a la izquierda", pero se desplaza a la derecha. Y el bucle for va de alto a bajo, prefiero ir de bajo a alto para cambiar a la derecha. –

+0

También movería el "int carry = 0;" dentro del ciclo while justo antes del ciclo for. –