Бит-сдвиг зависит от порядка байтов? - PullRequest
139 голосов
/ 25 августа 2011

Предположим, у меня есть число 'numb'=1025 [00000000 00000000 00000100 00000001]:

На машине Little-Endian:

00000001 00000100 00000000 00000000

На машине Big-Endian:

00000000 00000000 00000100 00000001

Сейчас, если я применю сдвиг влево на 10 битов (то есть: numb << = 10), у меня должно быть: </p>

[A] на машине с прямым порядком байтов:

Как я заметил в GDB,Little Endian выполняет сдвиг влево в 3 шага: [Я показал '3' шага, чтобы лучше понять только обработку]

  1. Обработать нет.в соглашении Big-Endian:

    00000000        00000000        00000100    00000001
    
  2. Применить сдвиг влево:

    00000000        00010000        00000100        00000000
    
  3. Представить результат снова в Little-Endian:

    00000000        00000100        00010000        00000000 
    

[B].На машине с прямым порядком байтов:

00000000        00010000        00000100        00000000

Мой вопрос:

Если я непосредственно применю сдвиг влево на конвенцию Little Endian, он должен дать:

numb:

00000001 00000100 00000000 00000000

numb << 10:

00010000 00000000 00000000 00000000

Но на самом деле это дает:

00000000        00000100        00010000        00000000 

Для достижения только второго результата, япоказали три гипотетических шага выше.

Пожалуйста, объясните мне, почему два вышеупомянутых результата отличаются: Фактический результат numb << 10 отличается от ожидаемого результата.

Ответы [ 4 ]

179 голосов
/ 25 августа 2011

Endianness - это способ хранения значений в памяти. При загрузке в процессор, независимо от порядкового номера, команда сдвига битов работает со значением в регистре процессора. Следовательно, загрузка из памяти в процессор является эквивалентом преобразования в старший порядок байтов, затем следует операция сдвига, а затем новое значение сохраняется в памяти, в которой порядок байтов с младшим порядком байтов снова вступает в силу.

Обновление благодаря @jww: на PowerPC сдвиги и повороты вектора чувствительны к порядку байтов. Вы можете иметь значение в векторном регистре, и сдвиг будет приводить к разным результатам в младшем и старшем порядковом порядке .

51 голосов
/ 25 августа 2011

Нет, битовое смещение, как и любая другая часть C, определяется в терминах значений , а не представлений.Сдвиг влево на 1 - это умножение на 2, сдвиг вправо - это деление.(Как всегда при использовании побитовых операций, остерегайтесь подписи. Все наиболее четко определено для целых типов без знака.)

4 голосов
/ 26 марта 2018

Какая бы команда сдвига не сдвинула биты старшего разряда в первую очередь, считается левым сдвигом. Какая бы команда сдвига ни сдвинула младшие биты первыми, считается правильным сдвигом. В этом смысле поведение >> и << для unsigned чисел не будет зависеть от порядка байтов.

3 голосов
/ 25 августа 2011

Компьютеры не записывают цифры так, как мы. Значение просто меняется. Если вы настаиваете на том, чтобы смотреть на него побайтово (хотя компьютер этого не делает), вы могли бы сказать, что на машине с прямым порядком байтов первый байт сдвигается влево, избыточные биты переходят во второй байт, и т. д.

(Кстати, младший порядок имеет больше смысла, если вы пишете байты по вертикали, а не по горизонтали, с более высокими адресами вверху. Именно так обычно и строятся диаграммы карты памяти.)

...