As a hobby project during Christmas I have been trying to make a better bin2bcd conversion than what you get if you use the two most typical methods, using itoa or mod (%). I have found a third method that is normally used in hardware. (Xilinx application
note XAPP029. It is not smaller (and will probably not be) but it is faster. Smallest is using mod. But I have not yet tried to make the code better than it is below, this is my first running version. Maybe someone could help me do it smaller (without causing it to be more than marginally slower) before I post the totall results.
unsigned short Short2BCD3(unsigned short inValue) // Overflow conversions (>=5). 1 is carry to next accumulator // 5 => 10 // 6 => 12 // 7 => 14 // 8 => 16 // 9 => 18 //Note: Only works with nibbles. { char BCDValue[5]; // 16 bits unsigned short can have a maximum of 5 digits // but currently only 4 are supported unsigned char loop; unsigned char acc0=0; unsigned char acc1=0; unsigned char acc2=0; unsigned char acc3=0; unsigned char carry0=0; unsigned char carry1=0; unsigned char carry2=0; unsigned char carry3=0; unsigned char carry4=0; unsigned char cIn0; for (loop=0;loop<=15;loop++) { // Put next bit of inValue in carry and shift up inValue one step. if (( inValue & 0x8000) != 0) // Check if MSB = 1 cIn0 = 1; // Yes, add one else cIn0=0; inValue <<= 1; // If carry generated to next digit, convert and add carry. // If no carry generated to next digit, shift left 1 step and add carry. if (carry1 == 1) acc0 = ((acc0-5)*2) + cIn0; else acc0 = (acc0 << 1) + cIn0; if (carry2 == 1) acc1 = ((acc1-5)*2) + carry1; else acc1 = (acc1 << 1) + carry1; if (carry3 == 1) acc2 = ((acc2-5)*2) + carry2; else acc2 = (acc2 << 1) + carry2; if (carry4 == 1) acc3 = ((acc3-5)*2) + carry3; else acc3 = (acc3 << 1) + carry3; // Check each accumulator if >= 5. Generate carry if so. if (acc0 >= 5) carry1 = 1; else carry1 = 0; if (acc1 >= 5) carry2 = 1; else carry2 = 0; if (acc2 >= 5) carry3 = 1; else carry3 = 0; if (acc3 >= 5) carry4 = 1; else carry4 = 0; } //END for return acc3<<12|acc2<<8|acc1<<4|acc0; }