Вопрос по c, endianness – Битовые операторы и «порядок байтов»

64

Есть липорядок байт вообще дело с побитовыми операциями? Илилогический или сдвиг?

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

В случае, если это имеет значение, я использую C.

Дубликат:stackoverflow.com/questions/7184789/… 0andriy
ИМХО, это немного разные вопросы. Этот вопрос похож на128 << 2 == 512 на любом процессоре? ", этот вопрос похож на"128 << 2 выложить как0x02 0x00 на любом процессоре? " kolen

Ваш Ответ

5   ответов
68

ко данные загружаются обрабатываемым процессором, порядковый номер полностью теряет актуальность. Сдвиги, побитовые операции и т. Д. Выполняются так, как вы ожидаете (данные логически представлены как младшие разряды в старшие) независимо от порядка следования байтов.

Не должно ли это быть "бит от высокого до младшего разряда"; логически?
@ legends2k: думал то же самое
@ legends2k: да. Сдвиг влево = умножить на степень 2. Сдвиг вправо = разделить на степень 2 (с округлением, отличным от целочисленного деления для отрицательных значений).
@JoshC: нет, PDP-10 просто выполнит операцию, как это логически определено для данных, независимо от того, какой именно бит размещен в его памяти / регистрах. Обратите внимание: когда вы добавляете два 32-разрядных целых числа, вам не нужно беспокоиться о том, что процессору необходимо преобразовать данные, чтобы добавление работало (и вы не беспокоитесь о порядке битов в байте в аппаратном обеспечении) - ALU просто делает "правильные вещи", потому что он подключен таким образом, что работает с его оборудованием. Сдвиги аналогичны - они работают с данными таким образом, что абстрагируют детали аппаратного порядка байтов / битов.
@JoshC: (продолжение) И в C операторы сдвига битов определены таким образом, что они абстрагируют их еще больше: они определяются в терминах значений, которые они производят, а не в том, как они перемещают лежащие в основе биты ( поэтому, если вы работаете на какой-то непонятной платформе, где команда аппаратного сдвига битов создаст недопустимую разметку битов, например, вы сдвинули бит значения в бит дополнения, требуется соответствующий компилятор для выработки инструкций, которые работают вокруг этого, так как Я понимаю, это).
3

вы можете прозрачно обращаться с порядком байтов.

Однако, если ваша операция включает в себя приведение нового типа, будьте осторожны.

Например, если вы хотите сдвинуть вправо некоторые биты и привести (явно или нет) к новому типу, значение порядка байтов!

Чтобы проверить свою последовательность, вы можете просто разыгратьint вchar:

int i = 1;

char *ptr;

...

ptr = (char *) &i;  //Cast it here

return  (*ptr);
... или создать союз ...{union { int i = 1; char a[4];} b;return b.a[3] == 1;} //big endian
4

сдвиги определяются спецификацией языка C и не зависят от порядкового номера, но реализация сдвига вправо может варьироваться в зависимости от того, использует ли архитектура одно или два арифметических дополнения.

1

но обычно языки программирования, такие как C, используют абстрактную последовательность в побитовых операциях. Так что нет, это не имеет значения в побитовых операциях.

@ Симеон: в то время, когда я писал этот ответ, этого не было. Изменения, внесенные одним автором за небольшой промежуток времени, будут объединены в один. Вот почему вы рассматриваете это как единственную ревизию.
Учитывая, что вопрос не имеет пересмотров, я удивлен, что вы говорите, что он не упомянул язык, когда он есть, и он также помечен как C.
60

>> оператор всегда сдвигает биты в направлении младшей цифры. Однако это не означает, что вы можете полностью игнорировать порядок байтов при их использовании, например, при работе с отдельными байтами в более крупной структуре вы не всегда можете предполагать, что они упадут в одном и том же месте.

short temp = 0x1234;
temp = temp >> 8;

// on little endian, c will be 0x12, on big endian, it will be 0x0
char c=((char*)&temp)[0];

Чтобы уточнить, я не принципиально не согласен с другими ответами здесь. Я хочу подчеркнуть, что хотя побитовые операторы по существу нейтральны по порядку байтов, вы не можете игнорировать эффект байтовости в вашем коде, особенно в сочетании с другими операторами.

Я добавил некоторые дополнительные разъяснения
Вы в основном не согласны со всеми, но ваш ответ был признан лучшим. Как определить поведение? Frank V
Да, я так думаю.
О. Так & gt; & gt; и & lt; & lt; не сдвиг вправо или влево вообще; они «смещаются в сторону наименее значимого» и «наиболее значимого». это делает «деление и умножение путем сдвига»; независимость от порядка байтов ... теперь я в замешательстве, если приведение через memcpy испортит это.
Так что для дальнейшего разъяснения вы имеете в виду, если только я на самом деле не получаю значения в байтах, это все нормально?

Похожие вопросы