Преобразовать целое число из (чистого) двоичного кода в BCD

м прямо сейчас тупо решить эту проблему ...

Я получаю номер BCD (каждая цифра является собственным 4-битным представлением)

Например, что я хочу:

Ввод: 202 (гекс) == 514 (дек)

Выход: BCD 0x415

Вход: 0x202

Битовое представление: 0010 0000 0010 = 514

Что я пробовал:

unsigned int uiValue = 0x202;
unsigned int uiResult = 0;
unsigned int uiMultiplier = 1;
unsigned int uiDigit = 0;


// get the dec bcd value
while ( uiValue > 0 )
{
    uiDigit= uiValue & 0x0F;
    uiValue >>= 4;
    uiResult += uiMultiplier * uiDigit;
    uiMultiplier *= 10;
}

Но я знаю этоочень неправильно, это будет 202 в битовом представлении, а затем разделить на 5 кусков и затем снова представить в виде десятичного числа

Я могу решить проблему на бумаге, но я просто не могу получить это в простом C-коде

 Sagi06 нояб. 2012 г., 10:10
Я добавил еще немного информации
 Daniel Gehriger06 нояб. 2012 г., 10:13
@ Андрей: Но он сказалuiValue = 202не0x202..., И если бы это было 0x202, то значение BCD было бы десятичным 202 ...
 Daniel Gehriger06 нояб. 2012 г., 10:19
@Sagi: Отсюда мой ответ ниже ...
 Sagi06 нояб. 2012 г., 10:18
@DanielGehriger: это правда, я тоже пришел к этому моменту в моих попытках
 panda-3406 нояб. 2012 г., 10:36
@ Саги, тамВ комментариях к моему ответу идет постоянное обсуждение того, хотите ли вы на самом деле BCD в качестве результата (как указано в вашем вопросе) или обычного int (как это делает заголовок вашего вопроса, а также первая редакция вашего вопроса). Пожалуйста, предоставьте двоичное представление правильного результата, который вы хотите для ввода 0010 0000 0010
 Andrew06 нояб. 2012 г., 10:12
202 hex = 514 dec = 514 BCD :)
 Andrew06 нояб. 2012 г., 10:35
Саги - не могли бы вы уточнить: Вы хотите конвертировать BCD в Uint (название вопроса) или Uint в BCD (код)?
 Andrew06 нояб. 2012 г., 10:34
Я, должно быть, схожу с ума, потому что я думал, что ключ был в названии: Binary Coded DECIMAL, а не BChex :)
 Sagi06 нояб. 2012 г., 10:11
@ Эндрю, это так правда, изменит это. Спасибо
 Daniel Gehriger06 нояб. 2012 г., 10:11
Твой код мне кажется вполне подходящим. десятичное число 202 - двоичное число 1100 1010, или, разбитое на кусочки: десятичное число 6 4 и, следовательно, двоично-десятичное представление десятичного числа 64.
 Andrew06 нояб. 2012 г., 10:10
Могу ли я предположить, что при работе с байтами и полубайтами шестнадцатеричные маски легче поместить в контекст? например, 0x0F более очевидно, чем 15 (по крайней мере для меня!)

Ответы на вопрос(5)

Решение Вопроса

Вы неправильно поняли. Ваш код конвертируется изBCD в двоичный файлкак ваш вопросS (оригинал) название говорит. Но указанные вами входные и выходные значения верны, только если вы конвертируете издвоичный в BCD, В этом случае попробуйте:

#include 

int main(void) {

   int binaryInput = 0x202; 
   int bcdResult = 0;
   int shift = 0;

   printf("Binary: 0x%x (dec: %d)\n", binaryInput , binaryInput );

   while (binaryInput > 0) {
      bcdResult |= (binaryInput % 10) < (shift++ < 2);
      binaryInput /= 10;
   }

   printf("BCD: 0x%x (dec: %d)\n", bcdResult , bcdResult );
   return 0;
}
 PapaAtHome22 окт. 2013 г., 10:13
Извините, мой предыдущий комментарий ошибочен, но я не могуубери это.
 Daniel Gehriger17 мая 2017 г., 21:49
@frr - ты, конечно, прав. Это была простая ошибка, и я исправил код. Спасибо за сообщение!
 Sagi06 нояб. 2012 г., 10:43
Спасибо, вот что мне нужно :)Почти тот же код, что и у меня, но я пошел не в ту сторону ... Спасибо
 frr16 мая 2017 г., 14:50
Большое спасибо, это помогло мне. Одно маленькое замечание: не уверен, что это была ваша цель, но выходной BCD-клев выходит упорядоченным "наименее значимый первый, В моем случае я хотел, чтобы клев вышелсамый значительный первыйТаким образом, мне пришлось сдвигать каждый клочок влево с увеличением, кратным 4 (смещение сразу после взятия по модулю), и только затем ИЛИ предварительно сдвинутый клев к результату. Обратите внимание, как алгоритм (% 10, / = 10) начинается с десятичных цифр младших разрядов и переходит к старшим.

Наивное, но простое решение:

char buffer[16];
sprintf(buffer, "%d", var);
sscanf(buffer, "%x", &var);
 fayyazkl06 нояб. 2012 г., 10:19
Isn»Т это будет производить гекс, где, как ОП попросил BCD? Они не эквивалентны. Я не'хотя голосую против. Это'какое-то тело еще
 panda-3406 нояб. 2012 г., 10:45
@ нет, я неНе знаю, должен ли я ответить на вопрос в заголовке, в теле вопроса или в примере кода. Oни'три разных.
 panda-3406 нояб. 2012 г., 10:29
@ Андрей, он начал хотеть, чтобы после моего ответа я ответил на первую ревизию, где он заявил, что только BCD был в BCD
 panda-3406 нояб. 2012 г., 10:20
С первой ревизии его вопроса было ясно, что он хотел преобразовать 202 в 514. Он делает именно это.
 Daniel Gehriger06 нояб. 2012 г., 10:49
@ panda-34: лично мне нравится ваше решение - и оно оказывается правильным, учитывая комментарий ОП к его принятому ответу.
 Andrew06 нояб. 2012 г., 10:26
Но он хочет 514 BCD, а не 514 Hex
 Andrew06 нояб. 2012 г., 10:31
Хорошо, хотя в его названии всегда указывалось BCD ... но, опять же, заголовок его вопроса выглядит неправильно для вопроса

Настоящая проблема здесь - смешение баз и единиц

202 должен быть шестнадцатеричным, что соответствует 514 десятичному знаку ... и, следовательно, вычисления BCD верны

Десятичный двоичный код преобразует десятичное число (514) в три поля размером с полубайт: - 5 = 0101 - 1 = 0001 - 4 = 0100

Большая проблема заключалась в том, что у вас неправильный заголовок, и вы конвертируете Uint в BCD, тогда как заголовок запрашивал BCD для Unint.

 Andrew06 нояб. 2012 г., 10:23
НЕТ, но я думаю, что это объясняет путаницу ... 0x202 == 514 (bcd), тогда как 202 (dec) == 202 (bcd)
 Andrew06 нояб. 2012 г., 10:40
10 == 0x0A имеетдвоичный представление 1010 да, ноДвоичный код в двоичном коде от 0001-0000. Два НЕ одинаковы
 Daniel Gehriger06 нояб. 2012 г., 10:20
Андрей, это 'не так сложно, как это. Нет необходимости конвертировать из шестнадцатеричного в десятичное, чтобы найти значение BCD.
 nos06 нояб. 2012 г., 10:33
@ Andrew It 'с другой стороны, 0x202 == 202 (bcd).
 Andrew06 нояб. 2012 г., 10:37
А? Пойдем проще ... 10d = 0Ah = (0001 0000) BCD == "10"не "0A»bcd ... так как же 0x202 == 202 BCD?
 nos06 нояб. 2012 г., 10:39
@Andrew 10d = 0Ah имеет двоичное представление 0000 1010, поэтому я думаю, это зависит от того, означает ли его 202 bcd, десятичное или шестнадцатеричное. КонечноuiValue = 202 неверно, хотя в тексте написано, что оно должно быть шестнадцатеричным:Input: 202 (hex) Если входное значение равно 0x202, как указано в тексте, двоичное представление входного значения равно 0000 0010 0000 0010, которое мы можем легко преобразовать в bcd.

Это решение, которое я разработал, отлично работает для встраиваемых систем, таких как микроконтроллеры Microchip PIC:

#include 
void main(){
    unsigned int output = 0;
    unsigned int input;
    signed char a;
    //enter any number from 0 to 9999 here:
    input = 1265;
    for(a = 13; a >= 0; a--){
        if((output & 0xF) >= 5)
            output += 3;
        if(((output & 0xF0) >> 4) >= 5)
            output += (3 < 4);
        if(((output & 0xF00) >> 8) >= 5)
            output += (3 < 8);
        output = (output < 1) | ((input >> a) & 1);
    }
    printf("Input decimal or binary: %d\nOutput BCD: %X\nOutput decimal: %u\n", input, output, output);
}

Попробуйте следующее.

unsigned long toPackedBcd (unsigned int val)
{
  unsigned long bcdresult = 0; char i;


  for (i = 0; val; i++)
  {
    ((char*)&bcdresult)[i / 2] |= i & 1 ? (val % 10) < 4 : (val % 10) & 0xf;
    val /= 10;
  }
  return bcdresult;
}
 597(packed BCD) - base 16
     H|    T|    U|        (Keep shifting left)
               11111111
             1 1111111
            11 111111  
           111 11111
          1010 11111    
 Niklas Rosencrantz30 мар. 2014 г., 13:01
Я проверяю эту функцию, и она, кажется, работает изначально, но у меня нетОн попробовал его для очень больших чисел или сравнил его эффективность с алгоритмом-кандидатом, чтобы выполнить преобразование, например, из11 в17 или аналогично. (Мой проект - C-код для 7-сегментных светодиодов Altera DE2 FPGA.)

Ваш ответ на вопрос