Continuing my Base 36 series, from last week’s Lesson, the base35_string() function successfully converts a decimal value into its base 36 representation. To verify that the conversion works, another function is necessary to convert base 36 strings into their decimal equivalents.
Converting bases requires a powers table. In the last two Lessons, the base 36 powers table is built in the main() function. But to convert both to and from base 36, the powers table must be available to multiple functions. Therefore, my first task in writing a base-36-to-decimal function is to write a function that provides the base 36 powers to other functions in the code.
The base36_powers() function builds the powers table and returns its address:
/* build the base 36 powers table */
long *base36_powers(void)
{
static long b36_powers[SIZE];
int x;
for( x=0; x<SIZE; x++ )
b36_powers[x] = x ? b36_powers[x-1]*BASE36_MAX : 1;
return(b36_powers);
}
This code is pulled from the main() function in previous Lessons, though the b36_powers[] array is declared static and its address returned. I suppose I could also hard code the values as an external array (set in a base 36 header file, for example) and call it good. But I chose to code the base36_powers() function instead.
With the powers table available, the next task is to create a b36_decimal() function to translate a base 36 string into its decimal value. Here’s the code:
/* return decimal value for base 36 string v */ long b36_decimal(char *v) { long *powers,result; int x,y,digit; /* obtain the powers table */ powers = base36_powers(); /* must process the string backwards */ x = 0; while( *(v+x) != '\0' ) /* locate the string's end */ x++; x--; /* backup to 1's position */ /* process the digits (x) and powers (y) */ result = 0; y = 0; while(x>=0) { /* translate digit */ if( *(v+x)>='0' && *(v+x)<='9' ) digit = *(v+x) - '0'; else digit = *(v+x) - 'A' + 10; /* fetch power value */ result += digit * *(powers+y); x--; y++; } return(result); }
After obtaining the powers table, the b36_decimal() function must process the incoming string backwards. A while loop locates the null character at the end of the string, setting this offset in variable x.
A second while loop works through the string in reverse order, but also uses variable y to process the powers table in forward order (starting with element zero). Digits are read and converted from characters '0' through '9' and 'A' through 'Z'. The result is multiplied by the proper power: result += digit * *(powers+y);
The value in variable result is returned.
Click here to view the full code on GitHub. The main() function prompts for a value, which is translated into base 36 and then translated back. Here’s a sample run:
Enter base 10 value: 12345
12345 in base 36 is 9IX
9IX in decimal is 12345
With these functions in place, it’s possible to do anything in base 36: Just perform the calculation in decimal and use the b36_decimal() and base36_string() functions to translate the results. I was originally going to code a slew of math functions that operated in base 36, but found the task to be silly given that all you really need to do is translate the results. After all, all calculations in a computer are done in base 2 anyway. Anything else you see is just for show.