Little endian Vs Big endian - PullRequest
       18

Little endian Vs Big endian

8 голосов
/ 12 февраля 2010

Допустим, у меня есть целое число 4Byte, и я хочу привести его к короткому целому числу 2Byte. Правильно ли я понимаю, что в обоих (в младшем и старшем порядке) короткое целое число будет состоять из 2 младших байтов этого целого числа 4Byte?

Второй вопрос:
Что будет результатом такого кода в процессорах с прямым и прямым порядком байтов?

int i = some_number;  
short s = *(short*)&i;

ИМХО в процессоре с прямым порядком байтов 2 были бы скопированы самые старшие байты, а в младшем порядке байтов 2 были бы скопированы младшие старшие байты.

Ответы [ 5 ]

12 голосов
/ 12 февраля 2010

Прав ли я, что оба коротких целых числа будут состоять из 2 младших байт этого целого числа 4 байта?

Да, по определению.

Разница между bigE и littleE в том, находится ли младший байт по младшему адресу или нет. На процессоре с прямым порядком байтов младшие адреса - младшие биты, x86 делает это так.

Они дают тот же результат на маленькой E.

short s = (short)i;
short s = *(short*)&i;

На процессоре с прямым порядком байтов старшие адреса - младшие биты, 68000 и Power PC делают это таким образом (фактически, Power PC может быть и тем и другим, но машины PPC от Apple используют bigE)

Они дают тот же результат на большом E.

short s = (short)i;
short s = ((short*)&i)[1]; // (assuming i is 4 byte int)

Итак, как вы можете видеть, little endian позволяет вам получить младшие биты операнда , не зная, насколько он велик . маленькая E имеет преимущества для сохранения обратной совместимости.

Так в чем же преимущество big endian? Он создает шестнадцатеричные дампы, которые легче читать.

Действительно, инженеры Motorola считали, что облегчение бремени чтения шестнадцатеричных дампов важнее обратной совместимости. Инженеры Intel считали обратное.

2 голосов
/ 12 февраля 2010
  1. Да. Когда вы конвертируете значения, вам не нужно беспокоиться о порядке байтов.

  2. Да. Когда вы конвертируете указатели, вы делаете.

1 голос
/ 12 февраля 2010

Если вы действительно хотите преобразовать int в short, просто сделайте это:

short int_to_short(int n) {
  if (n < SHRT_MIN) return SHRT_MIN;
  if (n > SHRT_MAX) return SHRT_MAX;
  return (short)n;
}

Вам не нужно даже беспокоиться о порядке байтов, язык обрабатывает это за вас. Если вы уверены, что n находится в диапазоне короткого замыкания, то вы также можете пропустить проверку.

1 голос
/ 12 февраля 2010

Вы должны знать, что ваш второй пример

int i = some_number;  
short s = *(short*)&i;

не является допустимым кодом C, поскольку он нарушает строгие правила наложения имен. Это может привести к сбою при некоторых уровнях оптимизации и / или компиляторах.

Используйте союзы для этого:

union {
   int   i;
   short s;
} my_union;

my_union.i = some_number;
printf("%d\n",my_union.s);

Также, как отмечали другие, вы не можете предполагать, что ваши целые числа будут 4 байта. Лучше использовать int32_t и int16_t, когда вам нужны определенные размеры.

1 голос
/ 12 февраля 2010

Прежде всего, вы, возможно, уже знаете это, но позвольте мне упомянуть, что размер int не гарантируется равным 4 байтам, а короткий - 2 байта для всех платформ.

Если в вашем первом вопросевы имеете в виду что-то вроде этого:

int i = ...;
short s = (short)i;

тогда да, s будет содержать младший байт (ы) i.

Я думаю, что ответ на ваш второй вопрос такжеда;на уровне байтов в игру вступает порядковый номер системы.

...