Прямой порядок байтов По сравнению с Обратным порядком байтов

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

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

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

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

8
задан Tomek Tarczynski 11 February 2010 в 21:12
поделиться

5 ответов

Прав ли я, что в обоих случаях короткое целое число будет состоять из 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 позволяет вам получить как минимум младшие значащие биты операнда , не зная, насколько он большой . Little E имеет преимущества для сохранения обратной совместимости.

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

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

12
ответ дан 5 December 2019 в 10:02
поделиться
  1. Да. Когда вы конвертируете значения, вам не нужно беспокоиться о порядке байтов.

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

2
ответ дан 5 December 2019 в 10:02
поделиться

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

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

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

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

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

1
ответ дан 5 December 2019 в 10:02
поделиться

Если вы действительно хотите преобразовать 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;
}

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

1
ответ дан 5 December 2019 в 10:02
поделиться

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

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

Реальный ответ для конкретной библиотеки обычно зависит от ее общей структуры. Легко представить «Boost» как нечто огромное. На самом деле это огромная коллекция библиотек, большинство из которых индивидуально довольно малы. Вы не можете сказать очень много (содержательно) о Boost в целом, потому что отдельные библиотеки написаны разными людьми, с разными техниками, целями и т.д. Некоторые из них (например, Format, Assign) действительно медленнее, чем почти все, что вы с большой вероятностью сделаете самостоятельно. Другие (например, Pool) предоставляют вещи, которые вы могли бы сделать сами, но, вероятно, не будут, чтобы получить хотя бы незначительные улучшения скорости. Некоторые (например, uBlas) используют магию шаблона большой мощности, чтобы работать быстрее, чем любой, но крошечный процент из нас может надеяться достичь самостоятельно.

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

Некоторые библиотеки также уделяют много места, кода (и часто, по крайней мере, битов времени) решению проблем, о которых вы вполне можете не заботиться. Например, много лет назад я использовал библиотеку обработки изображений. Его поддержка 200 + форматов изображения звучала действительно впечатляюще (и путь это было на самом деле), но я уверен, что никогда не использовал его, чтобы иметь дело с более чем десятком форматов (и я, вероятно, мог получить, поддержав только половину из них). OTOH, даже при всем, что все еще было довольно быстро. Поддержка меньшего количества рынков могла бы ограничить их рынок точка, что код был бы на самом деле медленнее (например, он обрабатывал JPEG быстрее, чем IJG).

-121--110â4-

Это можно сделать одним из двух способов в зависимости от требований к эффективности.

Менее эффективным методом является извлечение 10 * N предметов и сортировка и сокращение по мере необходимости:

# Fetch 10 most recent items from each type of object, sort by
# created_at, then pick top 10 of those.
@items = [ Ticket, Post, Report ].inject([ ]) do |a, with_class|
  a + with_class.find(:all, :limit => 10, :order => 'created_at DESC')
end.sort_by(&:created_at).reverse[0, 10]

Другим методом является создание индексной таблицы, которая имеет полиморфную связь с различными записями.Если вы заинтересованы только в показе 10 за раз, вы можете агрессивно обрезать это, используя какую-то задачу rake, чтобы ограничить его до 10 на пользователя, или какой-либо объем требуется.

-121--3713247-

Следует иметь в виду, что второй пример

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
ответ дан 5 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

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