Aquí está mi solución, pero aún más importante, mi enfoque para resolver el problema.
que abordó el problema por
- dibujar las celdas de memoria y dibujar flechas desde el destino al origen.
- hizo una tabla que muestra el dibujo de arriba.
- etiquetando cada fila en la tabla con la dirección de bytes relativa.
Esto me mostró el patrón:
- vamos
iL
ser el bajo nybble (medio byte) de a[i]
- vamos
iH
ser el alto nybble de a[i]
iH = (i+1)L
iL = (i+2)H
Este patrón es válido para todos los bytes.
Traduciendo en C, esto significa:
a[i] = (iH << 4) OR iL
a[i] = ((a[i+1] & 0x0f) << 4) | ((a[i+2] & 0xf0) >> 4)
Ahora hacer tres observaciones más:
- ya que llevamos a cabo las tareas de izquierda a derecha, que no necesitamos para almacenar cualquier valor en variables temporales
- tendremos un caso especial para la cola: todos
12 bits
al final será cero.
- debemos evitar leer la memoria indefinida más allá de la matriz. ya que nunca leemos más de
a[i+2]
, esto sólo afecta a los dos últimos bytes
Por lo tanto, nos
- manejamos el caso general de un bucle de
N-2 bytes
y realizar el cálculo general anterior
- manejar la siguiente al último byte por ella mediante el establecimiento de
iH = (i+1)L
- mango del último byte estableciéndolo en
0
dado a
con la longitud N
, obtenemos:
for (i = 0; i < N - 2; ++i) {
a[i] = ((a[i+1] & 0x0f) << 4) | ((a[i+2] & 0xf0) >> 4);
}
a[N-2] = (a[N-1) & 0x0f) << 4;
a[N-1] = 0;
Y ahí lo tienen ... la matriz se desplaza a la izquierda 12 bits
. Se podría generalizar fácilmente al cambio N bits
, teniendo en cuenta que habrá declaraciones de asignación M
donde M = number of bits modulo 8
, creo.
El bucle se podría hacer más eficiente en algunas máquinas mediante la traducción a los punteros
for (p = a, p2=a+N-2; p != p2; ++p) {
*p = ((*(p+1) & 0x0f) << 4) | (((*(p+2) & 0xf0) >> 4);
}
y mediante el uso de la mayor tipo de datos entero apoyado por la CPU.
(I acaba de escribir esto en, por lo que ahora sería un buen momento para que alguien revise el código, sobre todo porque poco haciendo girar es notoriamente fácil equivocarse.)
Esto desreferenciará más allá del final de la matriz cuando la matriz sea de longitud cero o solo contenga un solo byte. –