将整数从(纯)二进制转换为BCD

我现在愚蠢地解决这个问题……

我得到一个BCD号码(每个数字都是一个自己的4Bit表示)

例如,我想要的:

  • 输入:202(hex)== 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代码来解决它

你得到了错误的方式。 您的代码正在从BCD转换为二进制 ,正如您的问题(原始)标题所示。 但是,只有从二进制转换为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; } 

certificate: http : //ideone.com/R0reQh

一个天真但简单的解决方案:

 char buffer[16]; sprintf(buffer, "%d", var); sscanf(buffer, "%x", &var); 

这里真正的问题是基地和单位的混乱

202应该是HEX,相当于514十进制……因此BCD计算是正确的

二进制代码十进制将十进制(514)转换为三个半字节大小的字段: – 5 = 0101 – 1 = 0001 – 4 = 0100

更大的问题是你的标题是错误的,你将Uint转换为BCD,而标题要求BCD为Unint

请尝试以下方法。

 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; } 

也可以尝试以下变体(虽然可能效率不高)

 /* Copyright (c) 2016 enthusiasticgeek Binary to Packed BCD This code may be used (including commercial products) without warranties of any kind (use at your own risk) as long as this copyright notice is retained. Author, under no circumstances, shall not be responsible for any code crashes or bugs. Exception to copyright code: 'reverse string function' which is taken from http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059 Double Dabble Algorithm for unsigned int explanation 255(binary) - base 10 -> 597(packed BCD) - base 16 H| T| U| (Keep shifting left) 11111111 1 1111111 11 111111 111 11111 1010 11111 <-----added 3 in unit's place (7+3 = 10) 1 0101 1111 1 1000 1111 <-----added 3 in unit's place (5+3 = 8) 11 0001 111 110 0011 11 1001 0011 11 <-----added 3 in ten's place (6+3 = 9) 1 0010 0111 1 1 0010 1010 1 <-----added 3 in unit's place (7+3 = 10) 10 0101 0101 -> binary 597 but bcd 255 ^ ^ ^ | | | 2 5 5 */ #include  #include  //Function Prototypes unsigned int binaryToPackedBCD (unsigned int binary); char * printPackedBCD(unsigned int bcd, char * bcd_string); // For the following function see http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059 void reverse(char *str); //Function Definitions unsigned int binaryToPackedBCD (unsigned int binary) { const unsigned int TOTAL_BITS = 32; /*Place holder for bcd*/ unsigned int bcd = 0; /*counters*/ unsigned int i,j = 0; for (i=0; i>(TOTAL_BITS-1-i); /*shift by 1 place and append bit to lsb*/ bcd = ( bcd<<1 ) | binary_bit_to_lsb; /*printf("=> %u\n",bcd);*/ /*Don't add 3 for last bit shift ie in this case 32nd bit*/ if( i >= TOTAL_BITS-1) { break; } /*else continue*/ /* Now, check every nibble from LSB to MSB and if greater than or equal 5 - add 3 if so */ for (j=0; j>j; if(temp >= 0x5) { /*printf("[%u,%u], %u, bcd = %u\n",i,j, temp, bcd);*/ /*Now, add 3 at the appropriate nibble*/ bcd = bcd + (3<\n"); /* Now, check every nibble from LSB to MSB and convert to char* */ for (unsigned int j=0; j=4; j-=4) { unsigned int temp = (bcd & (0xf<>j; if(temp==0){ bcd_string[j/4] = '0'; } else if(temp==1){ bcd_string[j/4] = '1'; } else if(temp==2){ bcd_string[j/4] = '2'; } else if(temp==3){ bcd_string[j/4] = '3'; } else if(temp==4){ bcd_string[j/4] = '4'; } else if(temp==5){ bcd_string[j/4] = '5'; } else if(temp==6){ bcd_string[j/4] = '6'; } else if(temp==7){ bcd_string[j/4] = '7'; } else if(temp==8){ bcd_string[j/4] = '8'; } else if(temp==9){ bcd_string[j/4] = '9'; } else { bcd_string[j/4] = 'X'; } printf ("[%u - nibble] => %c\n", j/4, bcd_string[j/4]); } printf("<= [MSB]\n"); reverse(bcd_string); return bcd_string; } // For the following function see http://stackoverflow.com/questions/19853014/reversing-a-string-in-place-in-c-pointers#19853059 void reverse(char *str) { if (str != 0 && *str != '\0') // Non-null pointer; non-empty string { char *end = str + strlen(str) - 1; while (str < end) { char tmp = *str; *str++ = *end; *end-- = tmp; } } } int main(int argc, char * argv[]) { unsigned int number = 255; unsigned int bcd = binaryToPackedBCD(number); char bcd_string[8]; printPackedBCD(bcd, bcd_string); printf("Binary (Base 10) = %u => Packed BCD (Base 16) = %u\n OR \nPacked BCD String = %s\n", number, bcd, bcd_string); return 0; } 

这是我开发的解决方案,适用于嵌入式系统,如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); }