/************************************
 * convert.c -- Converts a number from
 *		one base to another, up to 5 places
 *		after the point precision.
 * 	        Without using stdlib functions in added code.
 *
 * by Ynori7
 * Feb 5, 2008
 ************************************/

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

/*****************************************************
 * Converts a character to its corresponding int:
 * chToInt('0') => 0, chToInt('a') => 11, chToInt('B') => 12, etc.
 ******************************************************/
int chToInt(char c) {
        char ls[]="0123456789abcdefghijklmnopqrstuvwxyz";
	char ls2[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	for (int x=0; x<strlen(ls); x++)
	{
		if(c==ls[x])
		{return x;}
		if(c==ls2[x])
		{return x;}
	}
	return 0;
}

/*************************************************
 * Converts an int to its corresponding char:
 * intToCh(1) => '1', intToCh(11) => 'a', intToCh(15) => 'f'
 *******************************************************/
char intToCh(int i) {
       char ls[]="0123456789abcdefghijklmnopqrstuvwxyz";
       return ls[i];
}


/***********************************************
 * convert: converts the string mInput from base
 *		mBase1 to mBase2, and returns a string representation
 ***********************************************/
char* convert(char* mInput, int mBase1, int mBase2) {
  char whole[99];
  char whole2[99];
  char fraction[99];
  char* output=malloc(sizeof(char)*100);
  int bTen=chToInt(mInput[0]);
  double bTenDec=0;
  int point=0;
  int x=0, y=0, w=0, p=0, exp=0;

  for(x=1; x<strlen(mInput); x++)//convert the whole part of the number into base 10
  {
	  if(mInput[x]=='.'){point=1; break;}
	  bTen*=mBase1;
	  bTen+=chToInt(mInput[x]);
  }

  if(point==1)//convert the fraction part of the number into base 10
  {
	  exp=1;
	  for(y=x+1; y<strlen(mInput); y++)
  	  {
		  bTenDec+=chToInt(mInput[y])* pow(mBase1, -exp);
		  exp++;
          }
  }
///////////////////////////////////////////////////////////////
  x=0;
  while( bTen > 0 )//convert the whole part of the base 10 number to the new base
  {
           whole[x] = intToCh(bTen%mBase2);
           bTen = (bTen-bTen%mBase2)/mBase2;
	   x++;
  }
  x--;
  w=0;
  for(x=x; x>=0; x--)//reverse it becuase it got stored in reverse order in the conversion
  {
	   output[w]=whole[x];
	   w++;
  }
///////////////////////////////////////////////////////////////
  y=0;
  while(1)//convert the fraction part of the base 10 number to the new base
  {
	   bTenDec*=mBase2;
	   if(floor(bTenDec)<bTenDec)
	   {
		fraction[y]=intToCh(floor(bTenDec));
		bTenDec-=floor(bTenDec);
	   }
	   else if(floor(bTenDec)==bTenDec)
	   {
		fraction[y]=intToCh((int)bTenDec);
		break;
	   }
	   y++;
  }
  if(y<5)
  {
	   y++;
	   for(y=y; y<5; y++)
	   {
		fraction[y]='0';
	   }
  }
  x=0;
  output[w]='.';
  w++;
  for(p=w; p<(w+y+1); p++)//put the whole and fraction parts together.
  {
	  output[p]=fraction[x];
	  x++;
  }
  output[p]='\0';
  return output;
}

/**************************
 * main function
 ***************************/
int main(int argc, char** argv) {
  if(argc < 4) {
    fprintf(stderr,"Error, not enough arguments.\n");
    fprintf(stderr,"Usage: convert number base1 base2\n");
    exit(1);
  }
  char* num = argv[1];
  char* num2;
  int tFrom = atoi(argv[2]);
  int tTo = atoi(argv[3]);

  num2 = convert(num, tFrom, tTo);

  printf("%s (base %d) = %s (base %d)\n",num, tFrom, num2, tTo);

  return 0;
}