Преобразование 8-битного в 32-битное

Я думаю, что запутался с порядком байтов и сдвигом битов, пожалуйста, помогите.

У меня есть 4 8-битных целых числа, которые я хочу преобразовать в 32-битное целое число. Вот что я делаю:

uint h;
t_uint8 ff[4] = {1,2,3,4};

if (BIG_ENDIAN) {
    h = ((int)ff[0] << 24) | ((int)ff[1] << 16) | ((int)ff[2] << 8) | ((int)ff[3]);
}
else {
    h = ((int)ff[0] >> 24) | ((int)ff[1] >> 16) | ((int)ff[2] >> 8) | ((int)ff[3]);
}

Однако это, кажется, дает неверный результат. Немного поэкспериментировав, я понял, что должно быть наоборот: в случае с прямым порядком байтов я должен сдвигать биты вправо, а в противном случае — влево. Однако я не понимаю, ПОЧЕМУ.

Вот как я это понимаю. Big endian означает, что старший байт идет первым (первый означает самый левый, правый? Возможно, здесь я ошибаюсь). Итак, преобразование 8-битного int в 32-битное int добавило бы 24 нуля к моим существующим 8 битам. Итак, чтобы сделать его 1-м байтом, мне нужно сдвинуть 24-й бит влево.

Пожалуйста, укажите, где я ошибаюсь.


person ivanibash    schedule 23.02.2014    source источник
comment
Ну, что такое ff[0] >> 24? Сделайте это вручную и посмотрите на результат. Это правильно?   -  person hyde    schedule 23.02.2014
comment
Может быть, попробовать сделать это с union ?   -  person AdamF    schedule 23.02.2014
comment
Вы говорите, что получили неверный результат. Какой результат вы получили и чем он отличается от того, что вы ожидали?   -  person Greg Hewgill    schedule 23.02.2014
comment
Каков порядок байтов в ff? Знаете ли вы, должен ли ff[0] быть старшим или наименее значащим байтом, или это зависит от порядка следования байтов машины? (Другими словами, как изначально были установлены байты в ff?)   -  person Kurt Revis    schedule 23.02.2014
comment
Операция побитового сдвига @hyde.   -  person ivanibash    schedule 23.02.2014
comment
Я имел в виду, какой результат вы получите за эту смену.   -  person hyde    schedule 23.02.2014
comment
@KurtRevis Код показывает, как были установлены байты. t_uint8 имеет размер 1 байт.   -  person ivanibash    schedule 23.02.2014
comment
Итак, ff[0] = 1 должен быть старшим значащим байтом или наименее значащим байтом? Это просто байты, и их можно интерпретировать в любом порядке; это полностью зависит от вас и вашего кода. Порядок байтов вашей машины не влияет на то, интерпретируете ли вы ff[0] как старший или младший значащий байт.   -  person Kurt Revis    schedule 23.02.2014


Ответы (1)


Вы всегда должны сдвигать 8-битные значения влево. Но в случае с прямым порядком байтов вы должны изменить порядок индексов так, чтобы четвертый байт шел в самую старшую позицию, а первый байт — в наименее значащую.

if (BIG_ENDIAN) {
    h = ((int)ff[0] << 24) | ((int)ff[1] << 16) | ((int)ff[2] << 8) | ((int)ff[3]);
}
else {
    h = ((int)ff[3] << 24) | ((int)ff[2] << 16) | ((int)ff[1] << 8) | ((int)ff[0]);
}
person nwellnhof    schedule 23.02.2014
comment
Означает ли это, что когда я привожу 8-битный int к 32-битному int, я всегда получаю дополнительные 24 нуля СЛЕВА, не относящиеся к порядку байтов? - person ivanibash; 23.02.2014
comment
Да (но только для значений без знака, для значений со знаком вы можете получить 24 единицы слева, если значение отрицательное). Endianness касается порядка байтов, а не порядка битов. - person nwellnhof; 23.02.2014
comment
@IvanInTheHat Когда вы преобразуете 8-битное целое число в 32-битное целое, значение не меняется. Итак, если вы посмотрите на это как на двоичное число на бумаге, единственное место, где вы можете добавить нули без изменения значения, действительно СЛЕВА. То, как он хранится в памяти в какой-либо архитектуре процессора, не имеет никакого отношения к тому, как он выглядит на бумаге или какое значение он должен сохранять. - person hyde; 25.02.2014
comment
@hyde, спасибо за еще одно объяснение, моя ошибка заключалась в том, что я думал, что сдвиг битов работает с необработанными битами в памяти. Мне указали, что это действительно не так, и сдвиг битов выполняется для математического значения, поэтому порядок байтов в этом случае не имеет значения. - person ivanibash; 26.02.2014