# Thread: Program that converts decimal to any base (mostly)

1. ## Program that converts decimal to any base (mostly)

I had the idea to write a program that would convert a decimal integer into any base up to 36 (there are no letters after that) so I decided to give it a try. I'm relatively new to the C language and I just wanted to see if anybody could give me some feedback on this code. I wanted to see if there are any areas in the code that could be improved even though the program seems to work alright.

Thanks

Code:
```#include <stdio.h>
#include <stdlib.h>

char letters(int r); // prototypes function for converting 10's to A's and so on, base 11+ will work
int main() {

int base;
int d;  //declares decimal integer
int d_clone;  // clones d for a loop
int r;  //declares remainder integer
int *number; //pointer variable to make an array based on how long the converted number is
int count = 0;  //these three are counters
int i = 0;
int j = 0;

printf("-- Decimal To Any Base Up to 36 Converter 0.1b --\n");
printf("\nEnter a decimal integer to convert: ");
scanf("%d", &d);
printf("\n");
printf("Enter the base you want it converted to: ");
scanf("%d", &base);
printf("\n");

d_clone = d;  //copies the decimal number for a loop

if(d < 0) {
printf("Cannot convert negative numbers.");
}  //end if

if(base==0 | base==1) {
printf("Cannot have 0 or 1 as a base.");
} //end if

else {

do {
r = d_clone % base;  //finds remainder everytime the number is divided by the base
d_clone = d_clone / base;  //divides the original number by the base

if(r >= 10) { // if the remainder is 10+ it will convert to letters
r = (char) r;
r = letters(r);
printf("%d R %c\n", d_clone, r);
count++;
} // end if

else {
r = (int) r;
printf("%d R %d\n", d_clone, r);
count++;  //counts how many times it is divisible, represents how long the number is
} //end else
} //end while
while(d_clone != 0); //stops when the number is 0

number = malloc(count * sizeof(int));  //allocates memory for the converted numbers digits

printf("\n");

do {
r = d % base;
d = d / base;
number[i] = r;  //sets the digits of the converted number in an array
i++;

}
while(i<count);  //executes loop until number[0] through number[i] are filled

j = count - 1; // accounts for the 0 index in the array

printf("The number in base %d is: ", base);

for(j = count - 1; j >= 0; j--) {
if(number[j] >= 10) {
number[j] = letters(number[j]);
printf("%c", number[j]);
} //end if

else {
printf("%d", number[j]);  //prints the converted number

} //end else
} //end for

free(number); //frees the allocated memory

} //end else

getch();

return 0;
}

char letters(int r) {

if(r==10){
return 'A';
}
if(r==11){
return 'B';
}
if(r==12){
return 'C';
}
if(r==13){
return 'D';
}
if(r==14){
return 'E';
}
if(r==15){
return 'F';
}
if(r==16){
return 'G';
}
if(r==17){
return 'H';
}
if(r==18){
return 'I';
}
if(r==19){
return 'J';
}
if(r==20){
return 'K';
}
if(r==21){
return 'L';
}
if(r==22){
return 'M';
}
if(r==23){
return 'N';
}
if(r==24){
return 'O';
}
if(r==25){
return 'P';
}
if(r==26){
return 'Q';
}
if(r==27){
return 'R';
}
if(r==28){
return 'S';
}
if(r==29){
return 'T';
}
if(r==30){
return 'U';
}
if(r==31){
return 'V';
}
if(r==32){
return 'W';
}
if(r==33){
return 'X';
}
if(r==34){
return 'Y';
}
if(r==35){
return 'Z';
}
}```

2. Line 30: if(base==0 | base==1)

It seems you wanted the logical "OR" (||) and not the bitwise "OR" (|).
(See here.)

Also, it would be a good idea to do some more rigorous validation on the input. An input of "127" at base "-2" yields funny results.

You can simplify the "letters()" function by figuring out a small algorithm, since each incremental value results in another incremental value. I was able to reduce the code in that function to a single line.

Overall, though, nice program.

3. Ah I see what you mean now.. I replaced the letters function with this:

Code:
```char letters(int r) { //converts numbers to ANSCII letters

return r + 55;
}```

4. Your new letters function is better, but still not ideal IMO. There is a way to do this with a string/array of all the possible digits for bases up to 36. It would reduce lines 73-81 to a single line, and basically eliminate the need for a letters function all together. It would also be much more portable.

Sounds like this is for school/fun, so you probably don't have to consider other systems that might use strange character sets, but still, it can't hurt to bring this up. First, your solution relies on you using something where 'A' is at 65. That is a pretty safe assumption, since most computers use ASCII or some ASCII compatible character set, but still not 100% certain. You could fix this by doing
Code:
`return r - 10 + 'A';`
However, that still has a problem. It relies on all the letters being contiguous, i.e. letters 'A'..'Z' are map to numbers 65 through 90, in standard alphabetical order, with no other letters, numbers, symbols or control chars between. Again, a fairly safe assumption nowadays, especially in your case, but not 100% safe.

Take a look at the EBCDIC character set as an example that would cause problems with your method.

5. To make it portable I would just do this

Code:
```char letters(int r) {
switch(r) {
case 10: return 'A';
case 11: return 'B';
case 12: return 'C';
/*...*/
case 35: return 'Z';
default: return '\0';
}
}```
It's more typing but that's what copy and paste is for.

6. EBCDIC? Absolute rubbish, and proof that dinosaurs are NOT all extinct. I would take it as a badge of honor that my programs wouldn't run on such crap.

"
Professor: "So the American government went to IBM to come up with an encryption standard, and they came up with—"
Student: "EBCDIC!"
"
< ROFL! >

(Thanks to Wikipedia)

7. A string would also make a great lookup table.

8. Code:
`"0123456789abcdefghijklmnopqrstuvwxyz"[number % base];`
...

9. Here's my function that converts base for comparison and scrutinizing.
Code:
```void itob( int n , char * string , int b ){
int i;
for( i = 0;n > 0; ++i ){
/* nums 0-9 have their respective ascii values inserted into string.
* higher nums have uppercase letters, starting with 'A' for num 10 */

string[ i ] = n % b + ( ( n % b <= 9 ) ? '0' : '7' );

/* adding '0' to the number turns it from a number 0-9 into the ascii version
adding '7' turns the number into the alphabetical equivilant
*/
n /= b;
}
string[ i ] = '\0';
reverse( string );
return;
}```
edit: I cannot take credit for the algorithm used as I pilfered it from the interwebz somewhere