Herramientas de usuario

Herramientas del sitio


bits

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
bits [2016/03/15 02:03] – [Ejemplo 2: extracción de bits] lmateubits [2018/03/22 12:57] (actual) – [Ejemplo 2: extracción de bits] lmateu
Línea 20: Línea 20:
  
   * x & MASK : borra aquellos bits de x que en la máscara MASK aparezcan en 0.   * x & MASK : borra aquellos bits de x que en la máscara MASK aparezcan en 0.
-  * x | MASK : colocar en 1 los bits de x que en MASK aparezcan en 0.+  * x | MASK : colocar en 1 los bits de x que en MASK aparezcan en 1.
  
 Por conveniencia se usan números hexadecimales para expresar las máscaras.  Ejemplos: Por conveniencia se usan números hexadecimales para expresar las máscaras.  Ejemplos:
Línea 51: Línea 51:
 El desplazamiento a la derecha se puede usar para dividir eficientemente por una potencia de 2.  Por ejemplo ''x %%>>%% 4'' corresponde a dividir por 16.  Aquí la diferencia en velocidad es mucho más importante: 1 ciclo versus muchos ciclos para una división.  Aquí hay que tener cuidado con los valores negativos.  ¿Cuanto debería ser %%-2 >> 1%%?  Uno esperaría que fuese -1, dado que se está dividiendo por 2.  Y en realidad sí lo es. El desplazamiento a la derecha se puede usar para dividir eficientemente por una potencia de 2.  Por ejemplo ''x %%>>%% 4'' corresponde a dividir por 16.  Aquí la diferencia en velocidad es mucho más importante: 1 ciclo versus muchos ciclos para una división.  Aquí hay que tener cuidado con los valores negativos.  ¿Cuanto debería ser %%-2 >> 1%%?  Uno esperaría que fuese -1, dado que se está dividiendo por 2.  Y en realidad sí lo es.
  
-La duda se produce porque si uno desplaza -2 en 1 bit hacia la derecha rellenando con un 0 a la izquierda, el resultado pasa a ser positivo, lo que no daría -1.  La explicación de por qué no sucede esto está en que cuando se usa un desplazamiento a la derecha de un entero con signo, no se rellena con 0, si nó que con el bit de signo.  En el caso de %%-2 >> 1%%, el bit de signo es 1 por lo que se rellena a la izquierda con un 1, preservando el signo negativo, y dando por lo tanto el resultado correcto -1.+La duda se produce porque si uno desplaza -2 en 1 bit hacia la derecha rellenando con un 0 a la izquierda, el resultado pasa a ser positivo, lo que no daría -1.  La explicación de por qué no sucede esto está en que cuando se usa un desplazamiento a la derecha de un entero con signo, no se rellena con 0, si no que con el bit de signo.  En el caso de %%-2 >> 1%%, el bit de signo es 1 por lo que se rellena a la izquierda con un 1, preservando el signo negativo, y dando por lo tanto el resultado correcto -1.
  
-Entonces cuando el tipo de la expresión a desplazar a la derecha es unsigned, entonces siempre se rellena con 0s a la izquierda.  Si es signed (con signo) se rellena con el bit de signo para preservar el signo del resultado.  En los desplazamientos a la izquierda siempre se rellena con 0s a la derecha.  Si un entero sin signo está formado por x<sub>0</sub> x<sub>1</sub> x<sub>2</sub> ... x<sub>30</sub> x<sub>31</sub>.+Entonces cuando el tipo de la expresión a desplazar a la derecha es unsigned, entonces siempre se rellena con 0s a la izquierda.  Si es signed (con signo) se rellena con el bit de signo para preservar el signo del resultado.  En los desplazamientos a la izquierda siempre se rellena con 0s a la derecha.  En resumen, dado un entero x formado por x<sub>0</sub> x<sub>1</sub> x<sub>2</sub> ... x<sub>30</sub> x<sub>31</sub>, éstos serían los posibles resultados de desplazar x en un solo bit:
  
 ^ tipo operando ^ operación ^ resultado ^ ^ tipo operando ^ operación ^ resultado ^
Línea 117: Línea 117:
 ===== Ejemplo 2: extracción de bits ===== ===== Ejemplo 2: extracción de bits =====
  
-Supongamos que un entero sin signo x está formado por x<sub>0</sub> x<sub>1</sub> x<sub>2</sub> ... x<sub>30</sub> x<sub>31</sub> Por razones de eficiencia de uso de la memoria se han colocado varios enteros de pequeño tamaño en el entero x.  Entonces se necesita programar la función extract(x, i, k) que entrega los bits x<sub>i</sub> ... x<sub>i+k-1</sub> de x, con %%0<=i<=31%% y %%0<k<32%%  Por ejemplo extract(0x048b6048, 0, 4) es 0 y extract(0x048b6048, 8, 12) es 0x8b6.+Supongamos que un entero sin signo x está formado por x<sub>0</sub> x<sub>1</sub> x<sub>2</sub> ... x<sub>30</sub> x<sub>31</sub> Por razones de eficiencia de uso de la memoria se han colocado varios enteros de pequeño tamaño en el entero x.  Por ejemplo, un entero podría estar codificado en los 12 bits ubicados en x<sub>8</sub> ... x<sub>19</sub>.  Entonces se necesita programar la función extract(x, i, k) que entrega los bits x<sub>i</sub> ... x<sub>i+k-1</sub> de x, con %%0<=i<=31%% y %%0<k<=32-i%% Por ejemplo extract(0x**0**48b6048, 0, 4) es 0 y extract(0x04**8b6**048, 8, 12) es 0x8b6.
  
-Como etapa previa necesitaremos de una función que entregue una máscara con los j bits menos significativos en 1.  Una forma errada de hacerlo sería calculando ''%%(1<<j)-1%%'' El problema es que esto no funcionaría en x86 si j=32.  Por lo tanto se debe considerar como un caso de borde.  Esta sería la función:+Como etapa previa necesitaremos de una función que entregue una máscara con los j bits menos significativos en 1.  Por ejemplo si j=4 la máscara sería 00...001111.  Una forma errada de hacerlo sería calculando ''%%(1<<j)-1%%'' El problema es que esto no funcionaría en x86 si j=32 porque en este procesador %%1<<32%% es 1, no 0 como uno esperaría.  Por lo tanto se debe considerar como un caso de borde.  Esta sería la función:
  
 <code> <code>
Línea 145: Línea 145:
 unsigned int extract(unsigned int x, int i, int k) { unsigned int extract(unsigned int x, int i, int k) {
   return (x<<i) >> (32-k);   return (x<<i) >> (32-k);
 +}
 +</code>
 +
 +y por último:
 +
 +<code>
 +unsigned int extract(unsigned int x, int i, int k) {
 +  return (  x & ( ((unsigned)-1)>>i ) ) >> (32-i-k);
 } }
 </code> </code>
bits.1458007420.txt.gz · Última modificación: 2016/03/15 02:03 por lmateu