Портативный способ разбиения n-байтового целого числа на отдельные байты - PullRequest
0 голосов
/ 18 января 2019

Проблема проста: взять 32-разрядное или 64-разрядное целое число и разделить его для отправки через (обычно) 1-байтовый интерфейс, такой как uart, spi или i2c.

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

Пример кода:

uint32_t value;
uint8_t buffer[4];
buffer[0] = (value >> 24) & 0xFF;
buffer[1] = (value >> 16) & 0xFF;
buffer[2] = (value >> 8) & 0xFF;
buffer[3] = value & 0xFF;

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

1 Ответ

0 голосов
/ 18 января 2019

Код, который вы представили, является самым переносимым способом сделать это. Вы преобразуете одно целое число без знака с шириной 32 бита в массив целых значений без знака с шириной ровно 8 бит. Полученные байты в массиве buffer имеют порядок с прямым порядком байтов.

Маскировка не нужна. From C11 6.5.7p5 :

Результатом E1 >> E2 является E1-сдвинутая вправо позиция бита E2. Если E1 имеет тип без знака или E1 имеет
тип со знаком и неотрицательное значение, значение результата является неотъемлемой частью отношения
E1 / 2 ^ E2.

и приведение к целому числу с шириной 8 битов (к значению) равно маскированию 8 битов. Таким образом, (result >> 24) & 0xff равно (uint8_t)(result >> 24) (значению). При назначении переменной uint8_t маскирование не требуется. Во всяком случае, я бы смело предположил, что он будет оптимизирован с помощью нормального компилятора.

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

...