¿Qué hace Y 0xFF?

Y un entero con 0xFF deja solo el byte menos significativo. Por ejemplo, para obtener el primer byte de un short s, puede escribir s & 0xFF. Esto se conoce típicamente como»enmascaramiento». Si byte1 es un solo tipo de byte (como uint8_t) o ya es menor que 256 (y como resultado son todos los ceros excepto el byte menos significativo) no hay necesidad de enmascarar los bits más altos, ya que ya son cero.

Consulte la respuesta de tristopiaPatrick Schlüter a continuación cuando pueda estar trabajando con tipos con signo. Al realizar operaciones de bits, recomiendo trabajar solo con tipos sin signo.

si byte1 es un tipo entero de 8 bits, entonces no tiene sentido : si es más de 8 bits, esencialmente le dará los últimos 8 bits del valor:

 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 & 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ------------------------------- 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

El peligro de la segunda expresión viene si el tipo de byte1 es char. En ese caso, algunas implementaciones pueden tener signed char, lo que resultará en una extensión de signo al evaluar.

signed char byte1 = 0x80;signed char byte2 = 0x10;unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));unsigned short value2 = ((byte2 << 8) | byte1);printf("value1=%hu %hx\n", value1, value1);printf("value2=%hu %hx\n", value2, value2);

imprimirá

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

Lo probé en gcc v3.4.6 en Solaris SPARC de 64 bits y el resultado es el mismo con byte1 y byte2 declarados como char.

TL; DR

El enmascaramiento es para evitar la extensión implícita de signos.

EDITAR: He comprobado que es el mismo comportamiento en C++.

EDIT2: Explicación de la extensión del signo solicitada.La extensión de signo es una consecuencia de la forma en que C evalúa las expresiones. Hay una regla en C llamada regla de promoción. C lanzará implícitamente todos los tipos pequeños a int antes de hacer la evaluación. Veamos qué pasa con nuestra expresión:

unsigned short value2 = ((byte2 << 8) | byte1);

byte1 es una variable que contiene el patrón de bits 0xFF. Si char es unsigned ese valor se interpreta como 255, si es signed es -128. Al hacer el cálculo, C extenderá el valor a un tamaño int (16 o 32 bits generalmente). Esto significa que si la variable es unsigned y mantendremos el valor 255, el patrón de bits de ese valor como int será 0x000000FF. Si es signed queremos el valor -128 cuyo patrón de bits es 0xFFFFFFFF. El signo se extendió al tamaño de la temporalidad utilizada para hacer el cálculo.Y así orando lo temporal dará el resultado equivocado.

En el ensamblaje x86 se realiza con la instrucción movsx (movzx para la extensión cero). Otras CPU tenían otras instrucciones para eso (6809 tenía SEX).

Deja una respuesta

Tu dirección de correo electrónico no será publicada.