snippetcMinor
Convert a number into a different base and return as string
Viewed 0 times
numberconvertintoreturndifferentandstringbase
Problem
I wanted to write a function that would take a
should return
The code is as follows:
I've ran a variety of test cases, such as both
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
#include
#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 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 < 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.Solution
Off by one
Your
When I ran your program passing in
When I set
Simplified expression
This expression:
Could be simplified to:
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
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:-h000000000000000000000000000000000000000000000000000000000000000When 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.Code Snippets
-h000000000000000000000000000000000000000000000000000000000000000result[j++] = c[(i--) - 1];result[j++] = c[--i];Context
StackExchange Code Review Q#116683, answer score: 6
Revisions (0)
No revisions yet.