Декодировать двоично-десятичную дробь (BCD) в беззнаковое целое

Значение, используемое в моем проекте, выражается 4-битными десятичными двоичными кодировками (BCD), которые изначально хранились в символьном буфере (например, указанном указателем const unsigned char *). Я хочу преобразовать входной поток символов BCD в целое число. Не могли бы вы показать мне эффективный и быстрый способ сделать это?

Пример формата данных и ожидаемый результат:

BCD*2; 1001 0111 0110 0101=9765
       "9"  "7"  "6"  "5"

Большое спасибо!


person Golden Lee    schedule 26.05.2011    source источник
comment
возможный дубликат Самый эффективный способ преобразования BCD в двоичный   -  person Bo Persson    schedule 26.05.2011
comment
@Bo Persson: Это сообщение на C #, а не на C ++   -  person forsvarir    schedule 26.05.2011
comment
@forsvarir: По общему принципу, решение на C # ничем не хуже любого другого. Однако я думаю, что мое решение, вероятно, более компактно, чем любое из решений в этом потоке. :-)   -  person Chris Jester-Young    schedule 26.05.2011


Ответы (2)


unsigned int lulz(unsigned char const* nybbles, size_t length)
{
    unsigned int result(0);
    while (length--) {
        result = result * 100 + (*nybbles >> 4) * 10 + (*nybbles & 15);
        ++nybbles;
    }
    return result;
}

length здесь указывает количество байтов во входных данных, поэтому для примера, данного OP, nybbles будет {0x97, 0x65}, а length будет 2.

person Chris Jester-Young    schedule 26.05.2011
comment
Большое спасибо Крису Джестеру-Яну. Я сравнил ваше решение с моим. Ваше решение быстрее. Я использовал pow в цикле while. - person Golden Lee; 26.05.2011

Самую правую цифру можно расшифровать так:

const unsigned int bcdDigit = bcdNumber & 0xf;

затем вы можете сдвинуть число вправо, чтобы следующая цифра стала самой правой:

bcdNumber >>= 4;

Это даст вам цифры в неправильном порядке (справа налево). Если вы знаете, сколько у вас цифр, вы, конечно, можете напрямую извлечь нужные биты.

Используйте, например, (bcdNumber >> (4 * digitIndex)) & 0xf; для извлечения digitIndex: й цифры, где цифра 0 - крайняя правая.

person unwind    schedule 26.05.2011
comment
Дорогая раскрутка, ‹br/› Спасибо за быстрый ответ. Мой шаблон функции преобразования должен понравиться ‹br/› unsigned int BCDn (unsigned int n, const unsigned char * data) ‹br/› где const unsigned char * - это указатель, указывающий на символьный буфер для 4-битных двоичных десятичных чисел. Например: ‹br/› const unsigned char * data = 1001011101100101; ‹Br/› - person Golden Lee; 26.05.2011