Зависит ли бит-сдвиг от конъюнктуры?

Предположим, что число 'numb'=1025 [00000000 00000000 00000100 00000001] представлено следующим образом:

На маленькой конечной машине:

00000001 00000100 00000000 00000000

На Big-Endian Machine:

00000000 00000000 00000100 00000001

Теперь, если я применил Left Shift на 10 бит (то есть: numb <= 10), я должен иметь:

[A] Мало-Endian Machine:

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

  • Относитесь к no. в Большой Эндианской конвенции:

    00000000        00000000        00000100    00000001
    
  • Применить Left-Shift:

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

    00000000        00000100        00010000        00000000 
    

[В]. На машине Big-Endian:

00000000        00010000        00000100        00000000

Мой вопрос:

Если я применил только левый сдвиг на маленьком конце Конвенции, он должен дать:

numb:

00000001 00000100 00000000 00000000

numb << 10:

00010000 00000000 00000000 00000000

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

00000000        00000100        00010000        00000000 

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

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

Ответ 1

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

Обновление, благодаря @jww: В PowerPC векторные сдвиги и вращение чувствительны к концу. Вы можете иметь значение в векторном регистре, и смена приведет к разным результатам в little-endian и big-endian.

Ответ 2

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

Ответ 3

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

Ответ 4

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

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