Как endianness меняет порядок элементов при преобразовании двух элементов массива uint32_t в один uint64_t?

Я не понимаю, как порядок байтов меняет порядок элементов массива uint32_t при преобразовании в uint64_t и наоборот.

Если я имею дело с байтами, хранящимися в массиве uint8_t из 8 элементов, если я напрямую преобразую его в uint64_t, используя приведение указателя и разыменование следующим образом:

uint8_t array[8] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xb0, 0xa0};
uint64_t u = *(uint64_t *)array; 

В системе с прямым порядком байтов u будет равно 0xa0b0ffeeddccbbaa

Но если у меня есть такой массив uint32_t:

uint32_t arr[2] = {0xaabbccdd, 0xeeffb0a0} ;
uint64_t U = *(uint64_t *)arr;

В системе с прямым порядком байтов U становится 0xeeffb0a0aabbccdd

Я интуитивно понимаю первый случай, но второй, с uint32_t, сбивает с толку! У меня проблемы с визуализацией расположения памяти во время преобразования, в последнем случае... Каждая помощь будет принята с благодарностью!

Endianess захватывает с самого начала на uint32_t arr[2]. Оба этих значения uint32_t хранятся в представлении endian для конкретной платформы. Это не относится к первому образцу и базовому массиву uint8_t. Считают, что.

WhozCraig 14.12.2020 05:33

Кроме того, «В системе с прямым порядком байтов u будет равно 0xa0b0ffeeddccbbbaa» -> код *(uint64_t *)array рискует вызвать проблемы с выравниванием.

chux - Reinstate Monica 14.12.2020 05:45

@WhozCraig Не могли бы вы уточнить больше? :)

Vivekanand V 14.12.2020 06:23

@chux-ReinstateMonica Можете ли вы подробнее рассказать о проблемах выравнивания?

Vivekanand V 14.12.2020 06:23

Пример говорил бы громче, чем что-либо еще. Думайте о том, что вы делаете, но в обратном направлении. Посмотрите на это. Подумайте, что делает представление с порядком байтов с каждым из этих значений uint32_t в этом массиве из двух.

WhozCraig 14.12.2020 06:53
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
6
222
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Endianess применяется индивидуально к каждому целому числу от 16 бит или больше. То есть на машине с прямым порядком байтов 32-битное целое число 0xaabbccdd хранится как dd cc bb aa.

Таким образом, массив из двух 32 целых чисел uint32_t [2] со значениями 0x11223344 и 0x55667788 хранится как
44 33 22 11 и 88 77 66 55 соответственно. В массиве элементы гарантированно хранятся непрерывно, поэтому в этом случае память будет выглядеть как 44 33 22 11 88 77 66 55.

Однако 64-битное целое число 0x1122334455667788 сохраняется как 88 77 66 55 44 33 22 11, потому что, опять же, порядок байтов применяется индивидуально к каждому целому числу. Вот почему вы не можете переинтерпретировать структуру памяти двух 32-битных целых чисел как 64-битное целое число на машинах с прямым порядком байтов.

Однако, если бы ЦП был с обратным порядком байтов, uint32_t [2] был бы сохранен как:
11 22 33 44 55 66 77 88, а затем получается то же представление, что и uint64_t со значением 0x1122334455667788.


В качестве примечания: преобразования *(uint64_t *)array в вашем коде представляют собой неопределенное поведение, поскольку они нарушают строгое сглаживание указателей и, возможно, также могут привести к смещению. Для безопасного преобразования между различными типами памяти вам необходимо использовать битовые сдвиги, memcpy или union.

Большое спасибо за ваш ответ! Благодаря вашему ответу я очень четко понял концепцию! :) Но я использовал эту технику преобразования из соображений эффективности. Но по вашему совету я буду использовать memcpy / union ! :)

Vivekanand V 14.12.2020 14:40

Другие вопросы по теме