Search code examples
calgorithmdata-structuresradixconverters

Using logarithms or other method to convert from any base to another base in C


I'm trying to write a C program to convert a number given a base, to any other base (Eg. base 2 binary number to base 8, or base 3 to base 16 hex). I've researched this quite a bit, and already read through a similar article, The math behind converting from any base to any base without going through base 10?] but in the explanation given, they utilize an array, which I am not allowed to do for this program.

Without writing a lengthy program with a method for each possible combination of base conversion, I don't see how this is possible without an array to store possible values. I do understand that there is a change of base formula with logs that allows me to change between number bases, but I am unclear how I would apply this, as this formula only gives a decimal number answer, which I would still need to convert.

int log_base_n(int n, int logof)
{
    double logBaseN = log10((double) logof) / log10((double) n);
    return (int) ceil(logBaseN);
}

Here is my binary to decimal conversion which I am trying to use as an intermediate step:

/**
* Convert decimal numbers to binary. Uses a greedy subtraction
* algorithm. Assumes max integer allowed is 2 to 16 power.
*
* @param numberToConvert
*/
void decToBin(int numberToConvert)
{
int power = 16;
double ans = pow(2, power);

if (numberToConvert > ans)
{
    printf("ERROR: Number too large to convert!\n");
    return;
}

while (ans > numberToConvert)
{
    power--;
    ans = pow(2, power);
}

printf("%d", 0);

int i = power;

while (i >= 0)
{

    ans = pow(2, i);
    numberToConvert = numberToConvert - ans;
    printf("%d", 1);
    i--;

    while ((pow(2, i) > numberToConvert) && (i >= 0))
    {
        printf("%d", 0);
        i--;
        ans = pow(2, i);
    }
   }
}

I know Java has a parseInt() method, that does base conversions, but is there something similar I can implement in C without having to write methods for each possible conversion like the one above, while still utilizing a logarithm related idea? Any help would be greatly appreciated.


Solution

  • but is there something similar I can implement in C without having to write methods for each possible conversion like the one above, while still utilizing a logarithm related idea?

    Logarithm is a poor choice. The computation of logs in code is not exactly the same as their mathematical counterpart and leads to incorrect output.

    The below is a problem should the quotient result in a value just a little higher than a whole number expected value. Of course, log10() is a problem for logof <= 0.

    double logBaseN = log10((double) logof) / log10((double) n);
    return (int) ceil(logBaseN);
    

    Further, the calculation of log_base_n() is quite unnecessary.

    This is an integer problem. Use integer math.


    A simply non-array solution "to convert from any base to another base"1 is to use recursion.

    void print_int_base(int numberToConvert, int base) {
      // For now, assume numberToConvert >= 0, 2 <= base <= 36
      if (numberToConvert >= base) {
        print_int_base(numberToConvert/base, base);
      }
      int digit = numberToConvert%base;
      int c = digit < 10 ? digit + '0' : digit + 'A';
      putchar(c);
    }
    

    Test code

    #include <stdio.h>
    
    void print_int_base_test(int numberToConvert, int base) {
      printf("%10d %2d:", numberToConvert, base);
      print_int_base(numberToConvert, base);
      puts("");
    }
    
    int main() {
      int numberToConvert = 42;
      for (int base=2; base<=20; base++) {
        print_int_base_test(numberToConvert, base);
      }
    }
    

    Output

    42  2:101010
    42  3:1120
    42  4:222
    42  5:132
    42  6:110
    42  7:60
    42  8:52
    42  9:46
    42 10:42
    42 11:39
    42 12:36
    42 13:33
    42 14:30
    42 15:2M
    42 16:2K
    42 17:28
    42 18:26
    42 19:24
    42 20:22
    

    1 OP's idea of conversion apparently is to print the int in various bases.