just as titleï¼ now i'am use this method: a=value%1000/100; b=value%100/10; c=value%10; but it's slow,any faster methods? thanksï¼
Don't see any BCD in your question. BCD would store the value 0..9 in four bits, which means that the conversion would be: a = (value >> 8) & 0x0f; b = (value >> 4) & 0x0f; c = value & 0x0f;
In your case, you seem to have a binary value 0..999 stored in a 16-bit integer and want to get out three decimal digits.
The alternative to using div instructions is to do a scan conversion. Basically (a non-optimized program to show the concept):
#include <stdint.h> #include <stdio.h> void convert(uint16_t value) { uint8_t a = 0,b = 0,c = 0; uint8_t a_tmp = 1,b_tmp = 0,c_tmp = 0; uint8_t overflow = 0; int bits_processed = 0; printf("value:%4u -> ",value); while (value) { // Find all non-zero bits in input value //printf("value %u %u %u %u\n",value,c_tmp,b_tmp,a_tmp); if (value & 1) { // We know the value of this bit, so add to our ouput bits. a += a_tmp; b += b_tmp; c += c_tmp; // Catch any decimal overflow to next digit. if (a >= 10) { a -= 10; b++; } if (b >= 10) { b -= 10; c++; } if (c >= 10) { c -= 10; overflow++; } } value >>= 1; if (!value) break; // Next bit to test is worth twice as much. a_tmp <<= 1; b_tmp <<= 1; c_tmp <<= 1; if (a_tmp >= 10) { a_tmp -= 10; b_tmp++; } if (b_tmp >= 10) { b_tmp -= 10; c_tmp++; } if (c_tmp >= 10) { c_tmp -= 10; overflow++; } if (++bits_processed >= 16) { printf("Internal error - hung algorithm\n"); return; } } printf(" %u %u %u",c,b,a); if (overflow) printf(" OVERFLOW!"); printf("\n"); } int main(void) { convert(1); convert(9); convert(11); convert(99); convert(117); convert(999); convert(4692); convert(9999); convert(54321u); convert(65535u); return 0; }
#define DIM(a) (sizeof(a) / sizeof(a[0])) void bin2bcd(unsigned long bin, unsigned char *bcd) { static const unsigned long pow_ten_tbl[] = { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; unsigned long pow_ten; unsigned char digit; unsigned char i; for (i = 0; i != DIM(pow_ten_tbl); i++) { digit = 0; pow_ten = pow_ten_tbl[i]; while (bin >= pow_ten) { bin -= pow_ten; digit++; } *bcd++ = digit; } }
i'am try you code,but it can't build success. Build target 'Target 1' compiling u32tobcd.c... U32TOBCD.C(23): warning C206: 'DIM': missing function-prototype U32TOBCD.C(23): error C267: 'DIM': requires ANSI-style prototype Target not created
my test code:
#include <reg52.h> #include <math.h> unsigned char bcdt[10]={0,0,0,0,0,0,0,0,0,0}; unsigned char *bcd; void bin2bcd(unsigned long bin, unsigned char *bcd) { static const unsigned long pow_ten_tbl[] = { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; unsigned long pow_ten; unsigned char digit; unsigned char i;
for (i = 0; i != DIM(pow_ten_tbl); i++) { digit = 0; pow_ten = pow_ten_tbl[i];
while (bin >= pow_ten) { bin -= pow_ten; digit++; } *bcd++ = digit; } }
void main(void) { while(1) { bin2bcd(1234567,*bcd); } }
View all questions in Keil forum