2011-03-30 20 views
5

Deje L y B sean dos máquinas. L orden sus bits de de LSB (Bit Menos Significativo) a MSB (bit más significativo) mientras B orden desde el MSB al LSB. O, en otras palabras, L usa Little Endian mientras que B usa Big Endian bit - no debe confundirse con el orden de bytes.¿Cómo afecta el bit endianismo a los cambios de bit y archivo IO en C?

Problema 1 RESUELTO:

Estamos escribiendo el siguiente código que se quiere ser portátil:

#include <stdio.h> 

int main() 
{ 
    unsigned char a = 1; 
    a <<= 1; 

    printf("a = %d\n", (int) a); 

    return 0; 
} 

en L, se imprimirá 2, pero lo que sucede en B? ¿Cambiará el 1 e imprimirá 0 ?.

SOLUCIÓN: La definición C99 en 6.5.7 dice que, al menos en tipos de enteros sin signo, << y >> se multiplique y divida por 2 respectivamente.

Problema 2:

Estamos escribiendo el siguiente código que se quiere ser portátil:

programa READ:

/* program READ */ 
#include <stdio.h> 

int main() 
{ 
    FILE* fp; 
    unsigned char a; 

    fp = fopen("data.dat", "rb"); 
    fread(&a, 1, 1, fp); 
    fclose(fp); 

    return 0; 
} 

y el programa de ESCRITURA:

/* program WRITE */ 
#include <stdio.h> 

int main() 
{ 
    FILE* fp; 
    unsigned char a = 1; 

    fp = fopen("data.dat", "wb"); 
    fwrite(&a, 1, 1, fp); 
    fclose(fp); 

    return 0; 
} 

lo sucede si ejecutamos ESCRIBIR en L, mo ve el archivo de datos a B y ejecuta LEER allí? Y si ejecutamos ESCRIBIR en B y luego LEER en L?

Disculpe si se trata de una pregunta frecuente. Busqué en Google durante horas sin suerte.

Respuesta

7

Bit Endianness no afecta a los datos almacenados en los discos en bytes. Byte Endianness lo hará.

Bit Endianness es algo que importa para las interfaces serie donde se envía un byte bit por bit, y el emisor y el receptor deben acordar el orden de bytes. Por ejemplo, el orden de los bits en los dispositivos SPI varía y debe consultar la hoja de datos antes de intentar leer desde el dispositivo.

Esto es lo Wikipedia dice en poco endianness:

Los términos bit endianness o a nivel de bits endianness rara vez se utilizan cuando hablando de la representación de un valor almacenado, ya que sólo son significativo para las raras arquitecturas de computadora donde cada bit individual tiene una dirección única. Sin embargo, se usan para referirse al orden de transmisión de bits en un medio en serie . Lo más a menudo que el orden se gestiona de forma transparente por el hardware y es el análogo a nivel de bit de poco-endian (bajo-bit primero), aunque existen protocolos que requieren el orden opuesto (por ejemplo I²C). En la red , la decisión sobre el orden de transmisión de bits se realiza en la parte inferior de la capa de enlace de datos del modelo OSI.

En su caso, la interfaz física del disco duro define el orden de los bits, independientemente del procesador que vaya a leerlo o escribirlo.

+0

Así que dices Endianidad de bits es irrelevante en el archivo IO. ¿Es esto algún tipo de estándar? Si es así, ¿puedes publicar enlaces a donde está definido? – rogi

+0

Ahora esto tiene sentido. – rogi

+0

E/S de archivo se define como la lectura de bytes completos. No puedes leer menos de un byte de un archivo. El orden de los bits depende de la interfaz con el medio de almacenamiento (SCSI, SATA, almacenamiento masivo USB, etc.) y me imagino que solo se verán afectadas las interfaces serie (por ejemplo, SATA pero no PATA). – tomlogic

2

El cambio de bit no se ve afectado por el endianness. La E/S de archivos binarios normalmente lo es, pero no en su caso, ya que solo está escribiendo un solo byte.

+1

Me preocupa _bit_ endianness y no _byte_. – rogi

+1

¿Qué plataforma tiene un endianness "bit" diferente ?! – EboMike

+1

En cualquier caso, cualquier cosa que no le dé "2" como resultado de "1 << 1" debe ir al depósito de chatarra, y rápido. – EboMike

0

Endianness no le afectará a menos que a) lea algo de la memoria con un tipo diferente al que solía escribir, o si lee algo de un archivo que se escribió con una máquina que usa endianness diferente.

decir

int data; 
char charVal; 

*data = 1; 
charval = *((char *) data); // Different result based on endianness 

O su ejemplo dos, asumiendo que usted está utilizando un tipo más grande que el char.

+0

Wat? Quiero saber sobre _bits_ y no _bytes_.Tu ejemplo es un comportamiento indefinido. – rogi

+3

Ver mis comentarios a la otra respuesta. Es posible que hayas malentendido algo. Big-endian y little-endian se refiere a la orden de bytes. – EboMike

+0

Me refiero a _bit_orden. La pregunta enfatiza eso. – rogi

3

El >> (y <<) no empuje (tire) los bits hacia la derecha (o hacia la izquierda).
Dividen (o múltiple) por 2.

Por todo el compilador le importa, los bits pueden ser apilados verticalmente :)

+1

Técnicamente, no es así. Hay una diferencia entre '/ 2' y' >> 1' cuando se usan números negativos. Además, dado que algunas CPU son mucho más lentas para dividir que para cambiar, sin duda harán una operación de cambio internamente. – EboMike

+0

De hecho, tiene casi razón. C99 estándar define >> y << como división y multiplicación por 2 en enteros sin signo. Añadiré esto a la pregunta. – rogi

+0

La sección 6.5.7 es algo densa para mignight ... pero el * valor * resultante de una expresión que utiliza cambios en modo bit se describe con división y multiplicación por 2. De todos modos +1 @Ebo para la diferencia con respecto a números negativos – pmg

4

No existe realmente el bit-endianness, al menos en lo que respecta a C. CHAR_BIT tiene que ser al menos 8 de acuerdo con la especificación, por lo que los accesos a cualquier objeto más pequeño que eso no tiene mucho sentido para un programa C estándar. Independientemente de cómo el hardware almacena un byte, primero LSB o MSB, no afecta en absoluto su programa. myVar & 1 devuelve el bit correcto en cualquier caso.

Si necesita interactuar con algún tipo de interfaz en serie y reconstituir bytes desde allí, esa es una historia diferente. La 'bit-endianness' de su máquina todavía no afecta nada, pero el orden de bits de la interfaz ciertamente sí lo hace.

Ahora, en cuanto a su pregunta específica y el programa que ha mostrado. Sus programas son casi 100% portátiles. Ni bit-ni byte-endianness los afecta. Lo que podría afectarles es si CHAR_BIT eran diferentes en cada plataforma. Una computadora podría escribir más datos de los que leería, o viceversa.

+0

Su respuesta me hizo pensar: si el tamaño del carácter está definido por la implementación, simplemente no hay forma de hacer ningún archivo portátil con fread y fwrite. ¿Estoy en lo cierto? – rogi

+1

@rogi, seguro que puede ser portátil, ¡solo asegúrese de copiar la cantidad correcta de bits! Puede usar la constante 'CHAR_BIT' para mantener sus programas portátiles. –

+0

Oh. ¡Gracias por tu respuesta! ¡Voy a hacer otra pregunta sobre este tema! – rogi