Just home-brewed code that does any base encoding. Comments on bad style
are welcome.
My favorite is the base-32 representation of the number 15.333...
It's F.ALALA...
== F*32^0 + A*(1/32) + L*(1/32)^2 + A*(1/32)^3 + L*(1/32)^4 + ...
== 15*32^0 + 10*(1/32) + 21*(1/32)^2 + 10*(1/32)^3 + 21*(1/32)^4 + ...
---
#include <string>
#include <iostream>
#include <math.h>
/******************************************************************************
* Given a value 'value' in base 10, convert it to a digit in base 'base'.
* PRECONDITION: 0 <= 'base' <= 36 (because of limit of alphabet size == 26)
******************************************************************************/
std::string val2digit(const int value, const int base) {
static const SIZE_OF_ALPHABET = int('Z') - int('A') + 1;
static const int GENERAL_NUMBER_BASE = 10;
static const int CHARS_PER_DIGIT = 2; // 1 is not enough!!!
std::string s = "";
if (value <= 9) {
char* buf = (char*)malloc(sizeof(char)*CHARS_PER_DIGIT);
itoa(value, buf, GENERAL_NUMBER_BASE);
s += buf;
free(buf);
}
else if (value <= 9 + SIZE_OF_ALPHABET) {
s += char((value - 9) + int('A')-1);
}
else {
printf("%s%d%s", "Error: Value must be in range 9 to ", 9 +
SIZE_OF_ALPHABET, "\n");
std::cout << std::flush;
}
return s;
}
/******************************************************************************
* Given a base-10 value 'n', convert it to a strong representation in base
* 'base', using a maximum of 'maxNumDecPlaces' number of decimal places.
******************************************************************************/
std::string base10ToBaseN(double n, const int base, int maxNumDecPlaces
= -1) {
static const int MAX_NUM_DEC_PLACES = 8;
maxNumDecPlaces = (maxNumDecPlaces < 0) ? MAX_NUM_DEC_PLACES :
maxNumDecPlaces;
int numDecPlaces = 0;
std::string s = "";
long p = long(log(n)/log(base)); // e.g., p = log(1056)/log(2) == 10
double m = pow(base, p); // e.g., m = pow(2,10) == 1024
long val;
bool hasDecPt = false;
// try all powers m that are <= the original n: m == (base^p,
base^(p-1),..., 1)
while ((n > 0 || m >= 1) && numDecPlaces < maxNumDecPlaces) {
if (!hasDecPt && m < 1) {
s += ".";
hasDecPt = true;
}
if (hasDecPt) {
numDecPlaces++;
}
val = long(n/m);
s += val2digit(val, base);
if (m <= n) {
n = n - val*m;
}
m = m/base; // e.g., m = 1024/2 == 512; m = 0.5/2 == 0.25
}
if (s[0]=='.') {
s = "0" + s;
}
return s;
}
/******************************************************************************
* Print the base 'base' representations of values in the base-10 range from
* 'min' to 'max', inclusive, using 'numIncsPerOne' increments between each
* base-10 step size of one. e.g., 'numIncsPerOne'==4 gives steps of 1/4 incs
*
* e.g., printBase(16, 0, 32, 4); // Print base-16 reps of 0..32, in 1/4 incs
******************************************************************************/
void printBase(const int base, const long min, const long max, const int
numIncsPerOne = 1) {
std::cout << "--- BASE " << base << "---\n";
double n;
for (long i=min; i<=max; i++) {
for (int j=0; j<numIncsPerOne; j++) {
n = double(i + double(j)/numIncsPerOne);
std::cout << n << ":\t\t" << base10ToBaseN(n, base) << "\n";
}
}
}
/******************************************************************************
* Test drive
******************************************************************************/
void main() {
printBase(32, 0, 32, 6); // Print base-16 reps of 0..32, in 1/6 incs
}
---