Ted Cost
Ted Cost

Reputation: 55

Decimal conversions to base numbers 2-16 (Binary through Hexadecimal)

Hey i'm writing a program that converts decimal numbers into any base unit from binary to hexadecimal (2,3,4,....,15,16). This is what I have so far, running any number from 2 - 15 results in an infinite loop. I was wondering if you had any advice for the rest of my project. When run, this will ask you for two integers, the first should be a decimal integer > 0, the second should be the base type you want it converted to. Any and all advice for completing this would be greatly appreciated! Thank you.

#include <stdio.h>
#include <stdlib.h>

int main(void){

  int x, y, z, c;

  printf("Please enter two integers: ");
  scanf("%d", &x);
  scanf("%d", &y);

  printf("%d\n", x);
  printf("%d\n", y);
  printf(" \n");

  if(y < 2 | y > 16){
    printf("You have entered incorrect information.\n");
           return 0;
  }
  else if(y > 1 && y < 16){

       while(z != 0){
       z = (x/y);
       c = (x%y);
       printf("%d\n", z);
       }
    printf("%d\n", z);
    printf("%d\n", c);
  }
      else if(y == 16){
        printf("%X\n", x);
      }

}

**********************edit**********************

#include <stdio.h>
#include <stdlib.h>

int main(void){

  int x, y, z, c, i;

  printf("Please enter two integers: ");
  scanf("%d", &x);
  scanf("%d", &y);

  printf("%d\n", x);
  printf("%d\n", y);
  printf(" \n");

  if(y < 2 || y > 16){
    printf("You have entered incorrect information.\n");
           return 0;
  }
  else if(y > 1 && y < 17){

    while(x != 0){
       c = (x%y);
       x = (x/y);

       if( c > 1 && c < 10){
       printf("%d", c);

    }else if( c == 10){
        c = printf("A");
    }else if( c == 11){
        c = printf("B");
    }else if( c == 12){
        c = printf("C");
    }else if( c == 13){
        c = printf("D");
    }else if( c == 14){
        c = printf("E");
    }else if( c == 15){
        c = printf("F");
   }
  }
    printf("\n");
}

This is the progress i've made so far. My problems are this: I cannot get the values A-F to output correctly to represent numbers 10-15. Also I cannot get the integers to be displayed the correct way. I think this is an easy fix, but a command I'm not used to yet. Thank you all for your help, it's been extremely beneficial.

*********edit 2 ************

#include <stdio.h>
#include <stdlib.h>

int main(void){

  int x, y, z, c; //Sets up variables to be used in program

  printf("Please enter two integers: "); //Asks for user input
  scanf("%d", &x);
  scanf("%d", &y); //stores input

  printf("%d\n", x);
  printf("%d\n", y);
  printf(" \n");

  if(y < 2 || y > 16){
    printf("You have entered incorrect information.\n");
           return 0;
  } //bug checks

  else if(y > 1 && y < 17){

    while(x != 0){
       c = (x%y);
       x = (x/y); // Loops numbers until a 0 value is reached, can be used with
                  // any Base

     if( c == 10){
        c = printf("A");
    }else if( c == 11){
        c = printf("B");
    }else if( c == 12){
        c = printf("C");
    }else if( c == 13){
        c = printf("D");
    }else if( c == 14){
        c = printf("E");
    }else if( c == 15){
        c = printf("F");
    }else{
        printf("%d", c);
    }
     // Returns for each remainer option
    }
    printf("\n");
  }
}

OKay third time is the charm. The only problem I have with my code now is that i cannot figure out how to make it output in reverse order, the proper order. Ignore my second edit, I solved that myself. Any input would be awesome. I don't really know how I'm going to get it to come out reversed. Thanks everyone!

Upvotes: 1

Views: 16358

Answers (6)

#include <stdio.h>
void main(void) {
    char base_digits[16] =
        {'0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    char converted_number[32];
    long int number_to_convert;
    int base, index=0;

    printf("Enter number and desired base: ");
    scanf("%ld %i", &number_to_convert, &base);

    while (number_to_convert != 0)
    {
        converted_number[index] = base_digits[number_to_convert % base];
        number_to_convert = number_to_convert / base;
        ++index;
    }
    --index;
    printf("\n\nConverted Number = ");
    for(  ; index>=0; index--)
    {
        printf("%c", converted_number[index]);
    }
    printf("\n");
}

Upvotes: 0

ChuckCottrill
ChuckCottrill

Reputation: 4444

This is fun. Some suggestions:

  • use descriptive variable names (base, remainder, digit, number, etc)
  • dont cheat, using %X is just wrong
  • how about supporting duodecadecimal (sp?), base 36?
  • print out useful symbols (letters?) for digit symbols larger than 9
  • consider termination conditions, you weren't changing z (remainder), thus your loop
  • you were printing out the number in reverse order, right to left instead of left to right

This version does up to base 36, printing letters for digit symbols > 9, and prints both reversed and expected order...

#include <stdio.h>
#include <stdlib.h>

char BASIFICATION[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int MAXBASE=36;
int main(void)
{
  int done=0;
  long num, base, remainder, digit;

  printf("Number Base Convertificator\n");
  printf("(enter 0 0 when done)\n");
  while( !done)
  {
    printf("Please enter two integers: ");
    scanf("%d", &num);
    scanf("%d", &base);
    if( (base<2) || (base>MAXBASE) ) //avoid precedence until you are comfortable/confident with it
    {
      printf("Please enter base between 2 and %d.\n",MAXBASE);
      if(base<=0) done=1;
      continue;
    }
    printf("%d\n", num);
    printf("%d\n", base);
    printf("\n");
    if(base == MAXBASE) //cheaters never win!
    {
      printf("%XX\n", num);
      continue;
    }
    //if(base > 1 && base < MAXBASE)
    {
      char reversed[99], ndx=0;
      //this prints your digits in reverse order
      remainder = num;
      while(remainder > 0) //numerical methods, avoid skipping below zero (irrelevant here, but good habit)
      {
         digit = (remainder%base);
         remainder = (remainder/base);
         printf("%c ", BASIFICATION[digit]);
         //printf("%c %d (%d)\n", BASIFICATION[digit], digit, remainder);
         reversed[ndx++] = BASIFICATION[digit];
      }
      printf("\n");
      //reverse digits to print in expected order
      for( ; ndx>0; ) { printf("%c ",reversed[--ndx]); }
      printf("\n");
    }
  }
}

And when run,

Number Base Convertificator
(enter 0 0 when done)
Please enter two integers: 1020 2
1020
2

0 0 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 0 0 
Please enter two integers: 252 16
252
16

C F 
F C 
Please enter two integers: 99 
8
99
8

3 4 1 
1 4 3 

Now, how would you modify this to convert an input string into a specified base?

Upvotes: 3

Eric Jablow
Eric Jablow

Reputation: 7889

The purpose of this program is to learn how to convert numbers to other bases, not just to try out printf when it gives you a shortcut. Why not try:

if (y > 1 && y <= 16) {
     parsedNumber = convert(x, y);
} else {
     reportIllegalBase(y);
}

with appropriate methods?

Also, don't use x and y for variable names. You are writing this for understanding, not to play Code Golf.

You should also try to make this a more general purpose program. Instead of printing everything as you calculate, construct a string (a char[]) and print that. So, the convert function I suggested you write should be declared as:

char[] convert(const int number, const int base) {...}

or

void convert(int * const buffer, const int number, const int base) {...}

By the way, what happens if x is negative? I'm not sure whether you do the right thing. You might want to get x from the user first, and then get y from the user. That way you can give the user a second chance if he types in 1 instead of 16:

int getBase() {
    int base;
    while(true) {
        printf("Please type in the base: ");
        scanf("%d", &base);
        if (base > 1 && base <= 16) {
            return base;
        } else {
            printf("\nThe base must be between 2 and 16 inclusively.  You typed %d.\n",
                base);
        }
     }
}

By the way, even though it isn't standard, there are reasons to use higher bases. A book I have titled Programming as if People Mattered by Nathaniel S. Borenstein (ISBN 0691037639) describes a situation where a college printed out randomly generated IDs on mailing labels. Unfortunately, sometimes the IDs looked like 2378gw48fUCk837 or he294ShiT4823, and recipients thought the school was cursing them.

A committee convened to suggest words that should not appear in those IDs. A student intern came up with this idea to make the committee unnecessary: Just use base 31 and leave out the vowels. That is, use 0123456789bcdfghjklmnpqrstvwxyz as the base-31 digits. This cut down on the work, made a lot of programming unnecessary, and put people out of a job.

Upvotes: 0

toor
toor

Reputation: 33

This is weird, you return 0, which means "everything went fine" when there is an error, and you won't return anything otherwise. Plus yea, you meant || not | You didn't initialize your z variable, it could never enter the loop if it is 0, and even worse, you are never affection new value to z, so if it is not 0, it will never be and you are in an infinite loop

Upvotes: 0

Tony Hopkinson
Tony Hopkinson

Reputation: 20320

Um introduction to an old style debugging process called dry run

x  y  z c (z != 0) 
16 2  8 0  true
      8 0  true DOH!

Upvotes: 1

Joni
Joni

Reputation: 111219

Since x is not modified in this loop, z is always calculated the same value, and the loop never exits:

   while(z != 0){
   z = (x/y);
   c = (x%y);
   printf("%d\n", z);
   }

To convert a number to a difference base, what you usually do is repeatedly divide the number by the base, and the remainders give you the digits. This will print out the digits from last to first:

   while(x != 0){
      c = (x%y); /* remainder of x when divided by y */
      x = (x/y); /* x divided by y */
      printf("%d\n", c);
   }

Upvotes: 1

Related Questions