Преобразование двоичного int в двоичный uint8_t в c - PullRequest
0 голосов
/ 13 октября 2018

У меня есть массив, определенный как

int data[k];

, где k - размер массива.Каждый элемент массива имеет значение 0 или 1. Я хочу сохранить двоичные данные в другом массиве, определенном как

uint8_t new_data[k/8];

(k обычно кратно 8).
Как я могу это сделатьв C?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Предполагая, что k является кратным 8, предполагая, что "каждый элемент является двоичным", вы подразумеваете "каждый int равен 0 или 1", также принимая биты в dataупакованы от наиболее значимых до наименее значимых, а байты new_data упакованы как big-endian (все разумные предположения), тогда вот как вы это делаете:

for (int i = 0; i < k/8; ++i)
{
    new_data[i] = (data[8*i  ] << 7) | (data[8*i+1] << 6)
                | (data[8*i+2] << 5) | (data[8*i+3] << 4)
                | (data[8*i+4] << 3) | (data[8*i+5] << 2)
                | (data[8*i+6] << 1) | data[8*i+7];
}
0 голосов
/ 13 октября 2018

Предполагая, что new_data начинается с 0, data[i] содержит только нули и единицы и что вы хотите заполнить младшие биты первыми:

for(unsigned i = 0; i < k; ++i) {
    new_data[i/8] |= data[i]<<(i%8);
}

Возможно более быстрая реализация 1 может быть:

for(int i = 0; i < k/8; ++i) {
    uint8_t o = 0;
    for(int j = 0; j < 8; ++j) {
        o |= data[i*8]<<j;
    }
    new_data[i] = o;
}

(обратите внимание, что это по существу предполагает, что k кратно 8)


  1. Как правило, оптимизировать проще, поскольку внутренний цикл имеетмаленькие, известные границы, и он записывает в переменную только с этой маленькой областью;оптимизаторам это легче обрабатывать, и вы можете видеть, например, что с gcc внутренний цикл полностью разворачивается .
...