2010-02-11 22 views
8

Digamos que tengo un entero de 4 bits y quiero convertirlo en un entero corto de 2 bits. ¿Tengo razón en que en ambos (pequeño y gran endian) el entero corto consistirá en 2 bytes menos significativos de este entero de 4 bits?Little endian Vs Big endian

Segunda pregunta:
¿Cuál será el resultado de dicho código en el procesador little endian y big endian?

int i = some_number; 
short s = *(short*)&i; 

mi humilde opinión en el procesador de big endian 2 bytes más significativos sería copiado, y en poco endian sería copiado 2 bytes menos significativos.

+0

Sugiero usar las matemáticas para reducir el número a un rango apropiado (tamaño) antes de copiar. Los compiladores mantendrán Endianness para que no tenga muchas preocupaciones. Copiar partes de las variables genera preocupaciones de Endianness como lo ha demostrado. –

Respuesta

12

¿Tengo razón en que los dos enteros cortos constarán de 2 bytes menos significativos de este entero de 4 bits?

Sí, por definición.

La diferencia entre bigE y littleE es si el byte menos significativo está en la dirección más baja o no. En un pequeño procesador endian, las direcciones más bajas son las menos significativas, x86 lo hace de esta manera.

Estos dan el mismo resultado en poco E.

short s = (short)i; 
short s = *(short*)&i; 

En un procesador de big endian, las direcciones más altos son los bits menos significativos, 68000 y Power PC hacerlo de esta manera (en realidad Power PC puede ser a la vez , sino máquinas PPC de Apple utilizan BIGE)

Estos dan el mismo resultado en gran E.

short s = (short)i; 
short s = ((short*)&i)[1]; // (assuming i is 4 byte int) 

por lo tanto, como se puede ver, Little endian le permite llegar a la LEA t bits significativos de un operando sin saber qué tan grande es. La pequeña E tiene ventajas para preservar la compatibilidad con versiones anteriores.

¿Cuál es la ventaja de big endian? Crea volcados hexadecimales que son más fáciles de leer.

Realmente, los ingenieros de Motorola pensaban que aliviar la carga de leer volcados hexadecimales era más importante que la compatibilidad con versiones anteriores. Los ingenieros de Intel creían lo contrario.

+0

No estoy seguro de que el argumento de compatibilidad con versiones anteriores sea muy fuerte, ya que los programas que asumen incorrectamente que algunas variables tienen un tamaño específico probablemente se rompen por otros motivos, incluso en una pequeña máquina endian (por ejemplo, cuando se trata de matrices). Creo que tiene más que ver con hacer cierta optimización de bajo nivel y otros trucos más fáciles, dentro del compilador o hardware. –

+0

@Josef: Sí, estoy seguro de que hubo muchas razones por las cuales los diseñadores de hardware preferían la pequeña E, y la compatibilidad puede no haber sido tan importante para ellos. Pero resulta que DIGO mucho al pasar del 80886 al 286/386. el código escrito para el 8088 aún se ejecuta en procesadores modernos x86/x64. –

+0

Sí, las arquitecturas x86 son compatibles retroactivamente a nivel binario, por diseño (para bien y para mal), al conservar siempre todo el conjunto de instrucciones de las generaciones anteriores. Es cierto que esto limita mi área de especialización, pero ¿ayuda endian poco en esta área, aparte de simplificar la lógica de circuitos ligeramente para las instrucciones mov? Todavía tiene códigos de operación diferentes para diferentes tamaños de datos (byte, palabra, dword, etc.). –

2
  1. Sí. Cuando conviertes valores, no tienes que preocuparte por la endianidad.

  2. Sí. Cuando conviertes punteros, lo haces.

+0

Y, en esencia, es la única vez que necesita convertir punteros de manera que sea importante, cuando serializa datos (es decir, archivos o E/S de red). Pero en ese caso, realmente tiene que preocuparse, ya que el lector puede usar una endianidad diferente. –

1

En primer lugar, es posible que ya lo saben, pero permítanme mencionar que el tamaño de int no se garantiza que sea de 4 bytes y la de cortos, 2 bytes en todas las plataformas.

Si en su primera pregunta que quiere decir algo como esto:

int i = ...; 
short s = (short)i; 

entonces sí, s contendrá el byte inferior (s) de i.

Creo que la respuesta a su segunda pregunta también es sí; en el nivel de bytes, la endianidad del sistema entra en juego.

1

Usted debe ser consciente de que su segundo ejemplo

int i = some_number; 
short s = *(short*)&i; 

no es código C válido, ya que viola las reglas de alias estricto. Es probable que falle bajo algunos niveles de optimización y/o compiladores.

Use los sindicatos para que:

union { 
    int i; 
    short s; 
} my_union; 

my_union.i = some_number; 
printf("%d\n",my_union.s); 

También, como otros han dicho, no se puede asumir que sus enteros serán 4 bytes. Es mejor utilizar int32_t e int16_t cuando necesite tamaños específicos.

+0

¿Cómo viola el alias estricto? –

+1

Escribir a un miembro de la unión y leer de otro es UB. – dalle

+0

esto no es una violación de aliasing. simplemente subvierte el sistema de tipos, nunca crea realmente un puntero. –

1

Si realmente desea convertir un int a un corto, a continuación, sólo hacer eso:

short int_to_short(int n) { 
    if (n < SHRT_MIN) return SHRT_MIN; 
    if (n > SHRT_MAX) return SHRT_MAX; 
    return (short)n; 
} 

Usted no tiene que preocuparse por endian, incluso, el idioma que maneja para usted. Si está seguro de que n está dentro del rango de un corto, entonces puede omitir el cheque también.

+0

No estoy preocupado, solo tenía curiosidad por saber cuál sería el resultado. –

Cuestiones relacionadas