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

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    2

    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. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    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. #3
    Registered User
    Join Date
    Jan 2013
    Posts
    2
    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;
    }
    Thanks for your feedback.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    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. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    A string would also make a great lookup table.

  8. #8
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Code:
    "0123456789abcdefghijklmnopqrstuvwxyz"[number % base];
    ...

  9. #9
    young grasshopper jwroblewski44's Avatar
    Join Date
    May 2012
    Location
    Where the sidewalk ends
    Posts
    294
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. decimal to base 8 algorithm
    By dbzx in forum C Programming
    Replies: 1
    Last Post: 04-10-2009, 03:02 AM
  2. Binary to Base 10 decimal conversion
    By JFonseka in forum C Programming
    Replies: 13
    Last Post: 11-20-2007, 04:14 PM
  3. Replies: 4
    Last Post: 08-24-2007, 05:28 PM
  4. Replies: 9
    Last Post: 10-07-2006, 05:37 AM
  5. program that converts CFG to CNF ?
    By Unregistered in forum C Programming
    Replies: 0
    Last Post: 09-19-2001, 11:57 AM