Как объединить верхний и нижний полубайты, хранящиеся последовательно в массиве? - PullRequest
2 голосов
/ 09 января 2009

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

{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ...}

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

{0xab, 0xcd, 0xef, ...}

Как я могу сделать это в C?

Ответы [ 4 ]

7 голосов
/ 09 января 2009

Что-то вроде

char *input, *output;
int i;
...
for(i=0; i<len; i+=2) {
  output[i/2]=(input[i]<<4) | input[i+1];
}

предоставил вывод в виде массива как минимум вдвое дольше, чем ввод, а верхние полубайты не были установлены на входе.

4 голосов
/ 09 января 2009

Не написав весь код для вас, вот подсказка:

unsigned int Nibble1 = 0x0A;
unsigned int Nibble2 = 0x0B;

unsigned int Result = (Nibble1 << 4) | Nibble2; // Result = 0xAB

Затем вам просто нужно написать цикл, который перебирает ваш входной массив по два элемента за раз и записывает в выходной массив.

Надеюсь, это поможет!

2 голосов
/ 09 января 2009

Только для пиков, вот версия, которая создает объединенный массив без использования второго массива. Он просто перезаписывает первую половину исходного массива новыми значениями:

char * writePtr = originalArray;
char * readPtr = originalArray;
while (readPtr < (originalArray + arraySize))
{
    *writePtr = (*readPtr << 4) | *(readPtr + 1);
    readPtr += 2;
    writePtr++;
}
0 голосов
/ 15 марта 2010

Может быть, это поможет вам, это не что иное, как простой художественный материал о клеве (верхний / нижний)

Эта система называется Binary Coded Decimal или BCD, которая также занимает клев. В BCD двоичные шаблоны с 1010 по 1111 не представляют действительные номера BCD и не могут использоваться.

Преобразование из десятичного в BCD является простым. Вы просто присваиваете каждой цифре десятичного числа один байт и преобразуете от 0 до 9 в 0000 от 0000 до 0000 1001, но вы не можете выполнить повторное деление на 2, как это было для преобразования десятичного числа в двоичное.

Давайте посмотрим, как это работает. Определите значение BCD для десятичного числа 5,319. Поскольку в нашем десятичном числе четыре цифры, в нашем BCD-номере четыре байта. Это:

Final Number is -5319

    Thousands               Hundreds             Tens                    Units 
       [5]                      [3]               [1]                      [9] 
    0 0 0 0 0 1 0 1      0 0 0 0 0 0 1 1     0 0 0 0 0 0 0 1     0 0 0 0 1 0 0 1 

Поскольку для хранения данных на компьютере требуется как минимум 1 байт, вы можете видеть, что верхняя часть каждого номера BCD является пустой памятью. BCD по-прежнему является системой взвешенных позиций, поэтому вы можете выполнять математику, но мы должны использовать специальные методы, чтобы получить правильный ответ.


УПАКОВАННЫЙ BCD

Поскольку хранилище на диске и в ОЗУ очень ценно, мы хотели бы устранить эту потерянную память. Это может быть достигнуто путем упаковки номеров BCD. В упакованном номере BCD каждый клев имеет взвешенную позицию, начиная с десятичной точки. Поэтому вместо того, чтобы требовать 4 байта для хранения BCD-номера 5319, нам потребовалось бы только 2 байта, половина хранилища. Верхний полубайт старшего байта нашего числа будет хранить значение THOUSANDS, в то время как нижний полубайт старшего байта будет хранить значение СТО. Аналогично, младший байт будет хранить значение TENS в верхнем полубайте и цифру UNITS в нижнем полубайте. Поэтому наш предыдущий пример будет:

Thousands - Hundreds          Tens - Units 
        [53]                       [19] 
0 1 0 1 0 0 1 1              0 0 0 1 1 0 0 1 
...