2010-11-12 23 views
4

Little Endian vs Big EndianLittle Endian - Big Endian problème

Big Endian = 0x31014950
Little Endian = 0x50490131

Cependant, l'utilisation de cette méthode

inline unsigned int endian_swap(unsigned int& x) 
{ 
return (((x & 0x000000FF) << 24) | 
     ((x & 0x0000FF00) << 8 ) | 
     ((x & 0x00FF0000) >> 8 ) | 
     ((x & 0xFF000000) >> 24)); 
} 

résultat = 0x54110131
i passé beaucoup de temps à essayer beaucoup de méthodes similaires et même une bibliothèque comme

unsigned long _byteswap_ulong(unsigned long value); 

mais toujours pas de chance .. tous les retours même résultat

EDIT
Je travaille sur Little-Endian système avec Microsoft Visual Studio 2008
l'exemple de la manière suivante

int main() 
{ 
    unsigned int y = 0x31014950; 
    unsigned int r = endian_swap(y); 
    std::cout << r; 
} 

l'exemple posté sur Ideone.com est correct .. mais ça ne marche pas avec moi

EDIT

std::cout << std::hex << r; 

Soit façons Pals .. Hex ou non ce n'est pas obtenir le bon numéro .. Soit Visual Studio a obtenu un grave erreur dans son Debugger ou toute ma machine ..
Parce que je remplacé le Code entier avec un code Redunant Plus lent mais toujours obtenir des résultats même
BTW si cela fait une différence .. J'utilise Debugger Break après la fonction pour vérifier le résultat

+0

Vous utilisez la valeur de retour, non? Tandis que vous prenez 'x' par référence, vous ne le modifiez jamais. –

+0

'endian_swap' semble bien. Et si le remplacer par une fonction de bibliothèque "renvoie le même résultat", peut-être votre problème est quelque part en dehors de cette fonction. – aschepler

+0

@James m'a fait penser que vous n'agissez même pas sur la valeur de 'x', vous faites tous les échanges sur la référence. Est-ce ce que vous voulez vraiment? – BeemerGuy

Répondre

1

Éliminer l'esperluette devant le x dans votre argumentation spécificateur. Vous voulez passer la valeur.

+0

Je ne sais pas pourquoi cela a été déprécié. – John

+0

@John: Ils n'ont pas dit, donc impossible de savoir, mais cela ne répond même pas au problème posé. –

+0

À un moment donné, il n'était pas clair si cela s'appliquait ou non, mais je pense que nous avons compris maintenant que cela ne causait pas le problème. – John

2
  • Imprimez-vous le résultat correctement?
  • Est-ce que le fait que vous passez une référence au lieu d'une valeur fait une différence?
+0

va supprimer la réfrence faire une différence? parce qu'apparemment ce n'est pas le cas:/ – VirusEcks

+1

Habituellement, vous passez par référence si vous voulez changer le paramètre transmis depuis la fonction. Vous ne semblez pas changer de 'x' du tout de votre fonction, donc passer en valeur rend votre intention plus claire (et peut-être correcte). :) – John

+0

OK, ce n'est pas la chose de référence. Problème intéressant! – John

2

Votre code semble être correct.

Le programme suivant (http://ideone.com/a5TBF):

#include <cstdio> 

inline unsigned int endian_swap(unsigned const int& x) 
{ 
return (((x & 0x000000FF) << 24) | 
     ((x & 0x0000FF00) << 8 ) | 
     ((x & 0x00FF0000) >> 8 ) | 
     ((x & 0xFF000000) >> 24)); 
} 

int main() 
{ 
    unsigned int x = 0x12345678; 
    unsigned int y = endian_swap(x); 
    printf("%x %x\n", x, y); 
    return 0; 
} 

sorties:


Edit:
vous avez besoin std::cout << std::hex << r, sinon vous Prin ting (1) mauvaise variable, et (2) en décimal :-)

Voir cet exemple: http://ideone.com/EPFz8

+0

indeeed .. il fonctionne avec des nombres comme celui-ci .. mais avec ces nombres hexadécimaux il échoue .. – VirusEcks

+1

C'est * est * un nombre hexadécimal. :) D'où ** 0x ** 12345678 – John

+0

Fait un exemple avec exactement votre numéro: http://ideone.com/Domrw – Vlad

0

Avez-vous unité testé votre code?

Sur ma plate-forme, ce passe:

void LittleEndianTest::testLittleEndian() 
{ 
    unsigned int x = 0x31014950; 
    unsigned int result = 
     (
      ((x & 0x000000FF) << 24) + 
      ((x & 0x0000FF00) << 8 ) + 
      ((x & 0x00FF0000) >> 8 ) + 
      ((x & 0xFF000000) >> 24) 
     ); 

    CPPUNIT_ASSERT_EQUAL((unsigned int)0x50490131, result); 
} 
0

L'exemple dans votre édition est la sortie y pas r. L'entrée y n'est, bien sûr, pas modifiée.

0

Si je cours le code que vous avez posté, il donne le bon résultat: endian_swap (0x31014950) == 0x50490131.

Pour obtenir le résultat: endian_swap (0x31014950) == 0x54110131, votre code doit être équivalent à ceci:

#define __ 
inline unsigned int endian_swap(unsigned int& x) 
{     //0x31014950 ->   0x54110131 
    return (((x & 0x000000FF) << 24) | // 50 
     __ ((x & 0x00F0F000) << 12) | // 4 
     __ ((x & 0x00FF0000) << 4 ) | // 1 
     __ ((x & 0x00FF0000) << 0 ) | //  1 
     __ ((x & 0x00FF0000) >> 8 ) | //  01 
     __ ((x & 0xFF000000) >> 24)); //  31   
} 

Vérifiez que vous n'avez pas des différences similaires dans votre code aussi.

+0

Je suis intéressé ... comment est-ce 12 .. et pas une multiplication de 8? – VirusEcks

+1

Pourquoi utiliser la macro? –

+0

@Roger Je mets l'IDE au code de formatage automatique à 4 espaces de retrait, donc utilisez-le si je veux formater à la main. –

0

Les opérateurs binaires ne sont pas utiles car ils fonctionnent comme si les bits étaient agencés dans l'ordre du bit le moins significatif au bit le plus significatif quel que soit l'ordre réel des octets internes.

void isBigEndian() 
{ 
    void *number; 
    number = (int *) new int(0x01000010); 
    // 0x01000010 
    // 01 00 00 10          Hexadecimal 
    // 0 1  0 0  0 0  1 0 
    // 0000 0001 0000 0000 0000 0000 0001 0000 Bit 
    // 1   0   0   16   Decimal 
    char *byte; 
    byte = (char *)number; 
    cout << static_cast<int>(*byte);//prints 16: Little Endian 
} 

Vous modifiez le nombre ci-dessus et le retournez 1 lorsqu'il est BigEndian.