Supposons que j'ai le nombre 'numb'=1025 [00000000 00000000 00000100 00000001]
représenté:
Sur la machine Little-Endian:
00000001 00000100 00000000 00000000
Sur une machine Big-Endian:
00000000 00000000 00000100 00000001
Maintenant, si j'applique Left Shift sur 10 bits (ie: numb << = 10), je devrais avoir:
[A] Sur la machine Little-Endian:
Comme je l'ai remarqué dans GDB, Little Endian effectue le décalage vers la gauche en 3 étapes: [J'ai montré les étapes «3» pour mieux comprendre le traitement uniquement]
Traitez le non. dans la Convention Big-Endian:
00000000 00000000 00000100 00000001
Appliquer le décalage vers la gauche:
00000000 00010000 00000100 00000000
Représentez à nouveau le résultat en Little-Endian:
00000000 00000100 00010000 00000000
[B]. Sur une machine Big-Endian:
00000000 00010000 00000100 00000000
Ma question est:
Si j'applique directement un décalage à gauche sur la convention Little Endian, cela devrait donner:
numb
:
00000001 00000100 00000000 00000000
numb << 10
:
00010000 00000000 00000000 00000000
Mais en fait, cela donne:
00000000 00000100 00010000 00000000
Pour atteindre le deuxième résultat uniquement, j'ai montré trois étapes hypothétiques ci-dessus.
Veuillez m'expliquer pourquoi les deux résultats ci-dessus sont différents: Le résultat réel de numb << 10
est différent du résultat attendu.
la source
Non, le décalage de bits, comme toute autre partie de C, est défini en termes de valeurs , pas de représentations. Le décalage vers la gauche de 1 est une multiplication par 2, le décalage vers la droite est la division. (Comme toujours lors de l'utilisation d'opérations au niveau du bit, méfiez-vous de la signature. Tout est mieux défini pour les types intégraux non signés.)
la source
x &= -1u << 20
sera probablement incorrect six
est 64 bits etint
32 bits. Pour cette raison, GCC promet de ne jamais traiter les équipes signées comme non définies ou même non spécifiées.Quelle que soit l'instruction de décalage qui décale les bits d'ordre supérieur en premier, est considérée comme le décalage à gauche. Quelle que soit l'instruction de décalage qui décale les bits d'ordre inférieur en premier, est considérée comme le décalage à droite. En ce sens, le comportement de
>>
et<<
pour lesunsigned
nombres ne dépendra pas de l'endianité.la source
Les ordinateurs n'écrivent pas les chiffres comme nous le faisons. La valeur change simplement. Si vous insistez pour le regarder octet par octet (même si ce n'est pas ainsi que l'ordinateur le fait), vous pourriez dire que sur une machine little-endian, le premier octet se décale vers la gauche, les bits en excès vont dans le deuxième octet, etc.
(À propos, little-endian a plus de sens si vous écrivez les octets verticalement plutôt qu'horizontalement, avec des adresses plus élevées en haut. Ce qui se trouve être la façon dont les diagrammes de carte mémoire sont généralement dessinés.)
la source
Bien que la réponse acceptée souligne que l'endianess est un concept du point de vue de la mémoire. Mais je ne pense pas que cela réponde directement à la question.
Certaines réponses me disent que les opérations au niveau du bit ne dépendent pas de l'endianess , et le processeur peut représenter les octets de toute autre manière. Quoi qu'il en soit, il parle de cette endianess est abstraite.
Mais lorsque nous faisons des calculs au niveau du bit sur le papier, par exemple, vous n'avez pas besoin de déclarer l'endianess en premier lieu? La plupart du temps, nous choisissons implicitement une fin.
Par exemple, supposons que nous ayons une ligne de code comme celle-ci
0x1F & 0xEF
Comment calculeriez-vous le résultat à la main, sur un papier?
Nous utilisons donc ici un format Big Endian pour faire le calcul. Vous pouvez également utiliser Little Endian pour calculer et obtenir le même résultat.
Btw, quand nous écrivons des nombres dans le code, je pense que c'est comme un format Big Endian.
123456
ou0x1F
, les nombres les plus significatifs commencent par la gauche.Encore une fois, dès que nous écrivons un format binaire d'une valeur sur le papier, je pense que nous avons déjà choisi une Endianess et nous regardons la valeur telle que nous la voyons dans la mémoire.
Revenons donc à la question, une opération de décalage
<<
devrait être considérée comme un passage de LSB (octet le moins significatif) à MSB (octet le plus significatif) .Puis comme pour l'exemple dans la question:
numb=1025
Petit endian
LSB 00000001 00000100 00000000 00000000 MSB
Ce
<< 10
serait donc10bit
passer du LSB au MSB.Comparaison et
<< 10
opérations pour le format Little Endian étape par étape:Hou la la! J'obtiens le résultat attendu comme décrit par l'OP!
Les problèmes que l'OP n'a pas obtenu le résultat attendu sont les suivants:
Il semble qu'il ne soit pas passé du LSB au MSB.
Lorsque vous déplacez des bits au format Little Endian, vous devez vous rendre compte (dieu merci, je le réalise) que:
LSB 10000000 00000000 MSB << 1
estLSB 00000000 00000001 MSB
, pasLSB 01000000 00000000 MSB
Parce que pour chaque individu
8bits
, nous l'écrivons en fait dans unMSB 00000000 LSB
format Big Endian.Alors c'est comme
LSB[ (MSB 10000000 LSB) (MSB 00000000 LSB) ]MSB
Pour résumer:
Bien que l'on dit que les opérations au niveau du bit sont abstraites blablablabla ..., lorsque nous calculons les opérations au niveau du bit à la main, nous avons encore besoin de savoir quelle extrémité nous utilisons lorsque nous écrivons le format binaire sur le papier. Nous devons également nous assurer que tous les opérateurs utilisent la même finalité.
L'OP n'a pas obtenu le résultat escompté parce qu'il a mal agi.
la source