I know you can use this table to convert decimal to BCD:
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 01
This code encodes and decodes. Benchmarks are as follows.
I used an uint64_t to store the BCD here. Very convenient and fixed width, but not very space efficient for large tables. Pack the BCD digits, 2 to char[] for that.
// -------------------------------------------------------------------------------------
uint64_t uint32_to_bcd(uint32_t usi) {
uint64_t shift = 16;
uint64_t result = (usi % 10);
while (usi = (usi/10)) {
result += (usi % 10) * shift;
shift *= 16; // weirdly, it's not possible to left shift more than 32 bits
}
return result;
}
// ---------------------------------------------------------------------------------------
uint32_t bcd_to_ui32(uint64_t bcd) {
uint64_t mask = 0x000f;
uint64_t pwr = 1;
uint64_t i = (bcd & mask);
while (bcd = (bcd >> 4)) {
pwr *= 10;
i += (bcd & mask) * pwr;
}
return (uint32_t)i;
}
// --------------------------------------------------------------------------------------
const unsigned long LOOP_KNT = 3400000000; // set to clock frequencey of your CPU
// --------------------------------------------------------------------------------------
int main(void) {
time_t start = clock();
uint32_t foo, usi = 1234; //456;
uint64_t result;
unsigned long i;
printf("\nRunning benchmarks for %u loops.", LOOP_KNT);
start = clock();
for (uint32_t i = 0; i < LOOP_KNT; i++) {
foo = bcd_to_ui32(uint32_to_bcd(i >> 10));
}
printf("\nET for bcd_to_ui32(uint_16_to_bcd(t)) was %f milliseconds. foo %u", (double)clock() - start, foo);
printf("\n\nRunning benchmarks for %u loops.", LOOP_KNT);
start = clock();
for (uint32_t i = 0; i < LOOP_KNT; i++) {
foo = bcd_to_ui32(i >> 10);
}
printf("\nET for bcd_to_ui32(uint_16_to_bcd(t)) was %f milliseconds. foo %u", (double)clock() - start, foo);
getchar();
return 0;
}
NOTE: It appears that it's impossible, even with 64-bit ints, to shift left more than 32 bits, but fortunately, it's entirely possible to multiply by some factor of 16 - which happily has the desired effect. It's also much faster. Go figure.