Зависит ли битовый сдвиг от endianness?

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

На Прямой Машина:

00000001 00000100 00000000 00000000

На Машине Больш-Endian:

00000000 00000000 00000100 00000001

теперь, если я применяю сдвиг влево на 10 бит (т. е.: numb

[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

мой вопрос:

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

numb:

00000001 00000100 00000000 00000000

numb << 10:

00010000 00000000 00000000 00000000

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

00000000        00000100        00010000        00000000 

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

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

4 ответов


Endianness-это способ хранения значений в памяти. При загрузке в процессор, независимо от endianness, инструкция битового сдвига работает на значении в регистре процессора. Таким образом, загрузка из памяти в процессор эквивалентна преобразованию в big endian, затем происходит операция сдвига, а затем новое значение сохраняется в памяти, где снова вступает в силу порядок байтов little endian.

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


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


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


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

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