2010-10-30 28 views
4
#define SwapByte4(ldata) \ 
    (((ldata & 0x000000FF) << 24) | \ 
    ((ldata & 0x0000FF00) << 8) | \ 
    ((ldata & 0x00FF0000) >> 8) | \ 
    ((ldata & 0xFF000000) >> 24)) 

Que représente 0x000000FF? Je sais que la décimale 15 est représentée en hexa comme F, mais pourquoi est-ce < < 24?Qu'est-ce que 0xFF et pourquoi est-il décalé 24 fois?

+0

1. vous n'avez pas besoin du \ à la fin de lignes. 2. Est-ce que je sens les devoirs? Si oui, veuillez marquer en conséquence –

+0

@Armen: Je suspecte que le début de la première ligne est "#define"; Comment est-ce que le marquage [travail à domicile] vous aiderait à mieux répondre à cette question? –

+0

@Roger: Ce ne serait pas. C'est juste une coutume dans SO d'étiqueter les questions de devoirs avec le tag –

Répondre

28

est ici une valeur hexadécimale, 0x12345678, écrit sous forme binaire, et annoté avec des positions de bits:

|31   24|23   16|15   8|7   bit 0| 
+---------------+---------------+---------------+---------------+ 
|0 0 0 1 0 0 1 0|0 0 1 1 0 1 0 0|0 1 0 1 0 1 1 0|0 1 1 1 1 0 0 0| 
+---------------+---------------+---------------+---------------+

... et voici 0x000000FF:

+---------------+---------------+---------------+---------------+ 
|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|1 1 1 1 1 1 1 1| 
+---------------+---------------+---------------+---------------+

Ainsi bitwise et sélectionne seulement les 8 bits inférieurs de la valeur d'origine:

+---------------+---------------+---------------+---------------+ 
|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 1 1 1 1 0 0 0| 
+---------------+---------------+---------------+---------------+

... et décalant la gauche de 24 bits, il se déplace à partir des 8 bits inférieurs vers le haut:

+---------------+---------------+---------------+---------------+ 
|0 1 1 1 1 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0| 
+---------------+---------------+---------------+---------------+

... qui est 0x78000000 en hexadécimal.

Les autres parties travaux sur les portions de 8 bits restants de l'entrée:

 0x12345678 
& 0x000000FF 
    ---------- 
    0x00000078 << 24 = 0x78000000  (as shown above) 

    0x12345678 
& 0x0000FF00 
    ---------- 
    0x00005600 << 8 = 0x00560000 

    0x12345678 
& 0x00FF0000 
    ---------- 
    0x00340000 >> 8 = 0x00003400 

    0x12345678 
& 0x00000000 
    ---------- 
    0x12000000 >> 24 = 0x00000012 

        | ---------- 
        0x78563412

sorte que l'effet global est de considérer la valeur 32 bits ldata comme une séquence de quatre octets de 8 bits, et inverser leur ordre.

+7

+1 pour ASCII Art; –

+0

Donc, fondamentalement, il s'agit d'un convertisseur Big Endian <=> de 32 bits. – Benoit

+0

grand merci quel sera le but de cela par peu Endian et big Endian – piyapiya

2

Vous devez regarder le 0x000000FF comme un masque de bits, c'est-à-dire où 1 vaut ldata et où 0 - 0 sera pris.

Pour comprendre le bitmask u besoin de le convertir en binaire, avec six pans il est très facile, chaque nombre hexadécimal est 4 chiffres binaires, à savoir:

hexagonaux 0 = binaire 0000 hex 1 = binaire 0001 etc.

Maintenant, pour les changements: notez que le décalage prend des données de la source, 8 bits exactement, et le déplace vers un autre emplacement dans la destination. Notez maintenant qu'il y a |, c'est-à-dire qu'il y a une opération OU sur toutes les opérations du masque de bits ET, les zéros resteront des zéros et dans le cas où il y a '1', le résultat en contiendra un.

Hope it helps :)

+0

ou son utilisé pour wkb .. – piyapiya

0

Disons données est un nombre de 32 bits représenté comme 0x12345678 (chaque nombre est de 4 bits en hexadécimal)

données & 0x000000FF signifie garder seulement les 8 derniers bits (appelé un masque de bits) = 0x00000078

les < < 24 moyens déplacent cette valeur pour les 24 bits de gauche (78 commence à la position 24 [0 index]) = 0x78000000

L'| signifie logique ou dans ce cas sera juste un ajout

Résultat final = 0x78563412

Lire sur les manipulations logiques

+0

merci .... mais quel est le but de tout cela. – piyapiya

+0

Dans ce cas, il s'agit de permuter l'endianess d'un nombre de 32 bits. Je ne voudrais pas écrire ceci comme un #define mais une fonction à la place. Voici une bonne lecture et pourquoi vous avez besoin de ces types de fonctions: http://en.wikipedia.org/wiki/Endianness – David

5

Ce genre de code a tendance à être utilisé pour échanger des choses entre le format big endian and little endian. Il y a aussi une petite astuce qui va convertir un mot dans un format connu (disons, peu endian) en quelque chose de l'endianisme de la machine actuelle, et vice versa. Cela irait à quelque chose comme ceci:

unsigned long littleEndian; 
unsigned char* littleBytes = &littleEndian; 
unsigned long result = 0; 
for (i = 0; i < 4; i++) 
    result += unsigned long(littleBytes[i]) << (8 * i); 

Cela fonctionne (en supposant que je ne l'ai pas foiré), car quelle que soit la façon dont les octets sont stockés, à gauche de changement est garanti à se déplacer vers bits les plus significatifs. La conversion en un caractère * vous permet d'accéder aux octets dans l'ordre dans lequel ils sont réellement stockés en mémoire. En utilisant cette astuce, vous n'avez pas besoin de détecter l'endianness de la machine pour lire/écrire des données dans un format connu. Certes, vous pouvez également utiliser les fonctions standard (hton, etc.): P

(Remarque: Vous devez faire attention et jeter le personnage avant de le déplacer, sinon il déborde simplement sur vos chaussures. n'est pas la seule option, | = aurait probablement plus de sens mais pourrait être moins clair si vous n'y êtes pas habitué, je ne suis pas sûr)

+0

pouvez-vous me dire sur le nombre significatif .. J'ai lu sur la représentation du point double et float mais je ne comprenais pas important. – piyapiya

+0

est-ce lié à la machine epsilon? – piyapiya

+0

par significatif Je veux juste dire plus de valeur, ou plus grand. Si j'ai le nombre 123, le chiffre le plus significatif est le 1, car il vaut 100. Même idée pour les bits et les octets dans un nombre. Certains octets de stockage de machine dans un ordre différent, de sorte que l'octet le plus significatif d'un nombre peut être stocké à la première adresse de mémoire, ou il peut être le dernier. – David