Convert a number into a different base and return as string I wanted to write a function that would take a long long int argument as well as a base and it would convert that number into an equivalent number in a different base, and return the result as a string (er, char array). For example, the call,

convertBase(9, 5)


should return "14\0". For negative values, the returned string should simply have a negative sign, '-' in front.

The code is as follows:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "convert.h"

#define MIN_BASE 2
#define MAX_BASE 36
#define MAX_LLI_REP 63

char toCharacter(int v)
{
    v = abs(v);
    return (v &lt; 10)
                ? ('0' + v)
                : ('a' + v - 10);
}

char * convertBase(long long int value, int base)
{
    if (base &lt; MIN_BASE || base &gt; MAX_BASE) {
        fprintf(stderr, "The base must be within [%d, %d].\n", MIN_BASE, MAX_BASE);
        return NULL;
    }
    char c[MAX_LLI_REP];
    int i, j = 0;
    long long int quotient;
    for (i = 0, quotient = value; quotient != 0; i++, quotient /= base)
    {
        c[i] = toCharacter(quotient % base);
    }
    int negative = value &lt; 0;
    char * result = (char *) malloc(sizeof(char) * (i + 1 + negative));
    if (negative) {
        result[0] = '-';
        j = 1;
    }
    while (i) {
        result[j++] = c[(i--) - 1];
    }
    result[j] = '\0';
    return result;
}


I've ran a variety of test cases, such as both LLONG_MIN and LLONG_MAX from limits.h, in various bases, as well as trying to convert a decimal number into a decimal number (expecting the same answer). It passed in all of these cases. However, I was wondering if additional sets of eyes could spot potential errors. Also, any stylistic or performance improvement suggestions would be appreciated.
Off by one

Your MAX_LLI_REP is 63, but since you are accepting long long inputs, you could have a 64 character representation if you pass in LONG_LONG_MIN which is 0x8000000000000000 and in binary would be 10000...000 which is one 1 and 63 0's.

When I ran your program passing in LONG_LONG_MIN (or -9223372036854775808), the first character in the output which should be a 1 was a random character instead, because it was the character that fell out of bounds and got overwritten by something else.  For example, I got:

-h000000000000000000000000000000000000000000000000000000000000000


When I set MAX_LLI_REP to 64, the problem went away.

Simplified expression

This expression:


result[j++] = c[(i--) - 1];



Could be simplified to:

result[j++] = c[--i];


Modified interface

Currently, you allocate a string and return it from your function.  This creates some potential awkwardness because someone has to free that string later on.

It might be nicer to pass in a buffer to your function and have the function fill it in instead.  The buffer size can be documented to be a minimum of 66 bytes, or you could pass in a buffer length argument as well and have the function fill up to the buffer length.

Alternatively, you could create a static buffer in your function and return a pointer to it.  This has the drawback that you must use the return value before you call the function again.  Some C library functions such as ctime() do this, so it isn't unprecedented.