One of the missing attributes of this "Convert long integer to base 36 string" is string management.
The below suffers from a potential buffer overflow when destination is too small.
char *long_to_string(char *destination, long num, int base);
(Assuming 32-bit long) Consider the overflow of below as the resultant  string should be "-10000000000000000000000000000000", which needs 34 bytes to encode the string.
char buffer[33];                     // Too small
long_to_string(buffer, LONG_MIN, 2); // Oops! 
An alternative would pass in the buffer size and then provide some sort of error signaling when the buffer is too small.
char* longtostr(char *dest, size_t size, long a, int base)
Since C99, code instead could use a compound literal to provide the needed space - without calling code trying to compute the needed size nor explicitly allocate the buffer. 
The returned string pointer from TO_BASE(long x, int base) is valid until the end of the block.
#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(long)*CHAR_BIT + 2)
//                               v. compound literal .v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))
char *my_to_base(char *buf, long a, int base) {
  assert(base >= 2 && base <= 36);
  long i = a < 0 ? a : -a;  // use the negative side - this handle _MIN, _MAX nicely
  char *s = &buf[TO_BASE_N - 1];
  *s = '\0';
  do {
    s--;
    *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(i % base)];
    i /= base;
  } while (i);
  if (a < 0) {
    s--;
    *s = '-';
  }
  // Could add memmove here to move the used buffer to the beginning
  return s;
}
#include <limits.h>
#include <stdio.h>
int main(void) {
  long ip1 = 0x01020304;
  long ip2 = 0x05060708;
  long ip3 = LONG_MIN;
  printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16), TO_BASE(ip3, 16));
  printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2), TO_BASE(ip3, 2));
  puts(TO_BASE(ip1, 8));
  puts(TO_BASE(ip1, 36));
  puts(TO_BASE(ip3, 10));
}