conversion - ¿Manipulación bit a bit simple para entero little-endian, en máquina big-endian?
little endian and big endian pdf (4)
aunque afectaría completamente a mi operación porque cambiaré incorrectamente (?)
No.
El resultado será el mismo independientemente de la arquitectura endian. Los cambios de bit y twiddling son como las operaciones aritméticas regulares. ¿Es 2 + 2
lo mismo en pequeñas arquitecturas endian y big endian? Por supuesto. 2 << 2
sería lo mismo también.
Los problemas pequeños y grandes de Endian surgen cuando se trata directamente con la memoria. Te encontrarás con problemas cuando hagas lo siguiente:
char bytes[] = {1, 0, 0, 0};
int n = *(int*)bytes;
En pequeñas máquinas Endian, n será igual a 0x00000001. En máquinas big endian, n será igual a 0x01000000. Aquí es cuando tendrás que intercambiar los bytes.
Para una necesidad específica, estoy construyendo un número entero de cuatro bytes de cuatro caracteres de un byte, sin usar nada demasiado especial (en mi pequeña plataforma endian):
return (( v1 << 24) | (v2 << 16) | (v3 << 8) | v4);
Soy consciente de que un entero almacenado en una máquina endian grande parecería AB BC CD DE
lugar de DE CD BC AB
de poca endianness, aunque afectaría completamente a mi operación en el sentido de que cambiaré incorrectamente, o solo causará un resultado correcto que se almacena en reversa y necesita ser revertido?
Me preguntaba si crear una segunda versión de esta función para hacer (aún desconocida) la manipulación de bits para una máquina big-endian, o posiblemente para usar la función ntonl relacionada, que no estoy seguro de cómo eso sabría si mi número está en el orden correcto o no.
¿Cuál sería su sugerencia para garantizar la compatibilidad, teniendo en cuenta que necesito formar enteros de esta manera?
FWIW, creo que mucho de lo que se ha dicho aquí es correcto. Sin embargo, si el programador ha codificado la endianidad en mente, digamos usando máscaras para la inspección y manipulación a nivel de bit, entonces los resultados multiplataforma podrían ser inesperados.
Puede determinar ''endianness'' en el tiempo de ejecución de la siguiente manera:
#define LITTLE_ENDIAN 0
#define BIG_ENDIAN 1
int endian() {
int i = 1;
char *p = (char *)&i;
if (p[0] == 1)
return LITTLE_ENDIAN;
else
return BIG_ENDIAN;
}
... y proceda en consecuencia.
Tomé prestado el fragmento de código de aquí: http://www.ibm.com/developerworks/aix/library/au-endianc/index.html?ca=drs- donde también hay una excelente discusión de estos temas.
hth -
Sidra de pera
Mientras trabaje en el nivel de valor , no habrá absolutamente ninguna diferencia en los resultados que obtenga independientemente de si su máquina es little-endian o big-endian. Es decir, siempre y cuando utilice operadores de nivel de lenguaje (como |
y <<
en su ejemplo), obtendrá exactamente el mismo resultado aritmético de la expresión anterior en cualquier plataforma. La endianidad de la máquina no es detectable y no es visible a este nivel.
Las únicas situaciones en las que debe preocuparse por la endianancia es cuando los datos con los que está trabajando se examinan en el nivel de representación del objeto , es decir, en situaciones en las que su representación de memoria sin formato es importante. Lo que dijo antes sobre " AB BC CD DE
lugar de DE CD BC AB
" se refiere específicamente al diseño de la memoria en bruto de los datos. Eso es lo que funciona como ntonl
do: convierten un diseño de memoria en otro diseño de memoria. Hasta el momento, no dio ninguna indicación de que el diseño de la memoria en bruto real sea de alguna manera importante para usted. ¿Lo es?
De nuevo, si solo te importa el valor de la expresión anterior, es total y totalmente independiente de endianness. Básicamente, no debe preocuparse por la endianidad cuando escribe programas en C que no intentan acceder y examinar los contenidos de la memoria en bruto.
[Reescrito para mayor claridad]
ntohl
(y ntohs
, etc.) se usa principalmente para mover datos de una máquina a otra. Si simplemente estás manipulando datos en una máquina, entonces está perfectamente bien hacer cambios de bit sin ninguna otra ceremonia: el cambio de bit (al menos en C y C ++) se define en términos de multiplicar / dividir por potencias de 2, por lo que funciona igual si la máquina es big-endian o little-endian.
Cuando / si necesita (al menos potencialmente) mover datos de una máquina a otra, normalmente es sensato usar htonl
antes de enviarlo, y ntohl
cuando lo reciba. Esto puede ser completamente nops (en el caso de BE to BE), dos transformaciones idénticas que se cancelan mutuamente (LE a LE), o en realidad dan como resultado el intercambio de bytes (LE a BE o viceversa).