¿Qué hace Y 0xFF?
En el siguiente código:
short = ((byte2 << 8) | (byte1 & 0xFF))
¿Cuál es el propósito de &0xFF
?
Porque otras veces lo veo escrito como:
short = ((byte2 << 8) | byte1)
Y eso parece funcionar bien también?
7 answers
Y un entero con 0xFF
deja solo el byte menos significativo. Por ejemplo, para obtener el primer byte en 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.
Ver tristopia La respuesta de Patrick Schlüter a continuación cuando puede estar trabajando con tipos firmados. Al realizar operaciones bitwise, recomiendo trabajar solo con tipos sin signo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-07 09:30:50
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 17:18:59
El peligro de la segunda expresión viene si el tipo de byte1
es char
. En ese caso, algunas implementaciones pueden tenerlo 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);
Se imprimirá
value1=4224 1080 right
value2=65408 ff80 wrong!!
Lo probé en gcc v3.4.6 en Solaris SPARC 64 bit y el resultado es el mismo con byte1
y byte2
declarado como char
.
TL; DR
El enmascaramiento es para evitar la extensión de signo implícita.
EDIT : He comprobado, es el mismo comportamiento en C++.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 07:37:07
Asumiendo que su byte1
es un byte(8bits), Cuando se hace un bit a bit Y de un byte con 0xFF, se obtiene el mismo byte.
Así que byte1
es lo mismo que byte1 & 0xFF
Decir byte1
es 01001101
, entonces byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1
Si el byte 1 es de algún otro tipo, digamos un entero de 4 bytes, a bit Y con 0xFF te deja con el byte menos significativo(8 bits) del byte 1.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 17:25:07
El byte1 & 0xff
asegura que solo los 8 bits menos significativos de byte1
pueden ser distintos de cero.
Si byte1
ya es un tipo sin signo que tiene solo 8 bits (por ejemplo, char
en algunos casos, o unsigned char
en la mayoría) no hará ninguna diferencia/es completamente innecesario.
Si byte1
es un tipo que está firmado o tiene más de 8 bits (p. ej., short
, int
, long
), y cualquiera de los bits excepto el 8 menos significativo se establece, entonces habrá una diferencia (es decir, cero los bits superiores antes or
ing con la otra variable, por lo que este operando de la or
afecta solo los 8 bits menos significativos del resultado).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 18:01:13
Borra todos los bits que no están en el primer byte
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 17:17:20
& 0xFF
por sí solo asegura que si los bytes son más largos que 8 bits (permitidos por el estándar de lenguaje), el resto se ignoran.
Y eso parece funcionar bien también?
Si el resultado termina siendo mayor que SHRT_MAX
, se obtiene un comportamiento indefinido. En ese sentido, ambos funcionarán igualmente mal.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-05 17:29:54