#include // 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); }