#include <stdio.h>
// This might not be very portable but works for Linux/Windows
union
{
unsigned char byte[4];
unsigned long v;
} reg;
// internal dump of intermediate steps so you can see what's happening
void dump(char *s)
{
int i;
printf("%s: ",s);
for (i=sizeof(reg.byte)-1;i>=0;i--) printf("%x ",reg.byte[i]);
printf("\n");
}
int main(int argc, char **argv)
{
char buf[65];
int n,i=0;
// Get a number to play with
printf("Number (decimal)?");
gets(buf);
reg.v=atoi(buf);
// loop 8 times
while (i!=8)
{
printf("%d\n",i++); // debug output
dump("Base");
// The idea is we are going to shift the number left
// 8 places to the "new" location
// but.. on each shift we will look to see if a
// BCD digit is >=5... if so the next shift shoul
// give us 10 but will instead give us A
// so if that's the case, add 3 so you get 8 (or 9 or 10, etc.)
// and double that will be 0x10, 0x11, 0x12...
// Since the max output is 255 there is no reason
// to test the top digit
if ((reg.byte[1]&0xF)>=5) reg.byte[1]+=3;
if ((reg.byte[1]>>4&0xF)>=5) reg.byte[1]+=0x30;
dump("Add");
// so now that we've adjusted things, shift
reg.v<<=1;
dump("Shift");
}
// final result is in reg.byte[2] (MSD) and packed in reg.byte[1]
printf("\nResult: %d%d%d\n",reg.byte[2]&0xF,reg.byte[1]>>4,reg.byte[1]&0xF);
}