Generic numerical systems conversion This program is a start point to a more comprehensive program that deals with different numerical systems from binary until 35 base. That includes the traditional decimal, octal and hex.

It is until 35 only, because no more digits other than the number 0-9 and the letters A-Z to represent digits for higher base systems.

The program needs a lot of validation code and other stuff. However, I would like to ask if the conversion from/to the decimal is good or you can show me a better approach.

My main focus is the algorithms for the conversion functions and the helper functions. 

Notes:


I do not want to use the built-in pow() function; I wrote my own version.  
I do not want to use ASCII in character conversions.




#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

string digit = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int power(int base, int exp)
{
    int result = 1;

    for (int i = 0; i &lt; exp; ++i)
        result = result * base;

    return result;
}

int val(char ch)
{
    ch = toupper(ch);

    for (int i = 0; i &lt; 37; ++i)
        if (digit[i] == ch)
            return i;

    return -1;
}




char chr(int d)
{
    return digit[d];
}

string int_to_string(int n)
{
    string result = "";
    int divisor = 10;
    int num = n;
    int r;
    int length = 0;

    while (num &gt; 0)
    {
        num = num / 10;
        ++length;
    }

    num = n;
    divisor = power(10, length) / 10;

    while (num != 0)
    {
        r = num / divisor;
        num = num % divisor;
        result += chr(r);
        divisor /= 10;
    }

    return result;
}


string to_decimal(string str, int base = 10)
{
    if (base == 10) return str;
    if (base &lt; 2 || base &gt; 37) return "Error: base out of range";
    int length = str.length();
    if (length &lt; 1) return "Error: No Number";
    int result = 0;

    for (int i = length - 1; i &gt;= 0; --i)
        result = result + power(base, length - i - 1) * val(str[i]);

    return int_to_string(result);
}

string from_decimal(string str, int base = 10)
{

    if (base == 10) return str;
    if (base &lt; 2 || base &gt; 37) return "Error: base out of range";
    int length = str.length();
    if (length &lt; 1) return "Error: No Number";

    string result = "";
    int divisor = base;
    int num = 0;
    int r;

    for (int i = 0; i &lt; length; ++i)
        num = num + power(10, length - i - 1) * val(str[i]);

    while (num != 0)
    {
        r = num % divisor;
        num = num / divisor;
        result = chr(r) + result;
    }

    return result;
}

bool is_valid(string str, int frombase)
{
    for (char ch : str)
        if (val(ch) &gt;= frombase)
            return false;
    return true;
}

string baseconvert(string str, int frombase,int tobase)
{
    if(is_valid(str, frombase))
        return from_decimal(to_decimal(str,frombase), tobase);
    else
        return "Error: Improper Number used!\n";
}

int main()
{
    cout &lt;&lt; baseconvert("FZ", 16,8) &lt;&lt; "\n\n\n";
    cout &lt;&lt; baseconvert("FE", 16,2) &lt;&lt; "\n\n\n";
}
Instead of trying to create your own versions, you could try doing it without.

Not wanting to use ASCII conversions makes sense since that would be inefficient.  using a string to get the char value from a specific integer value, works well.  However, to go the other way a map would work better, and ignores how the native mapping works.

map&lt;char,int&gt; values = 
{
    {'0',0},
    {'1',1},
    {'2',2},
    {'3',3},
    {'4',4},
    {'5',5},
    {'6',6},
    {'7',7},
    {'8',8},
    {'9',9},
    {'A',10},
    {'B',11},
    {'C',12},
    {'D',13},
    {'E',14},
    {'F',15},
    {'G',16},
    {'H',17},
    {'I',18},
    {'J',19},
    {'K',20},
    {'L',21},
    {'M',22},
    {'N',23},
    {'O',24},
    {'P',25},
    {'Q',26},
    {'R',27},
    {'S',28},
    {'T',29},
    {'U',30},
    {'V',31},
    {'W',32},
    {'X',33},
    {'Y',34},
    {'Z',35}
};


Using a power function  reiterates over the same loop over and over again each time you call it.  It would make more sense to start at the end of the string and increase a multiplier in each iteration of the existing loop.  Also when working with base 10 it is alot simpler to keep the values as integers:

int ToBase10(string value, int base)
{
    int decValue = 0;
    int baseMult = 1;
    for (int i = value.size()-1; i &gt; -1; i--)
    {
        decValue += values[value[i]] * baseMult;
        baseMult *= base;
    }
    return decValue;
}


Since decimal has other meanings, it would be clearer to say base10 instead.

Lastly wrapping your functions up in a static class allows you to expose only what needs to exposed.  Also this keeps the validation in only one place:

#include &lt;map&gt;
using std::map;
using std::string;
class BaseConverter
{
    static map&lt;char, int&gt; values;
    static bool GoodValue(string&amp; value, int base);
    static string FromBase10(int value, int base);
    static int ToBase10(string value, int base);
public:
    static string Converter(string value, int fromBase, int toBase);
    static string Converter(int decValue, int base);
};

map&lt;char,int&gt; BaseConverter::values = 
{
    {'0',0},
    {'1',1},
    {'2',2},
    {'3',3},
    {'4',4},
    {'5',5},
    {'6',6},
    {'7',7},
    {'8',8},
    {'9',9},
    {'A',10},
    {'B',11},
    {'C',12},
    {'D',13},
    {'E',14},
    {'F',15},
    {'G',16},
    {'H',17},
    {'I',18},
    {'J',19},
    {'K',20},
    {'L',21},
    {'M',22},
    {'N',23},
    {'O',24},
    {'P',25},
    {'Q',26},
    {'R',27},
    {'S',28},
    {'T',29},
    {'U',30},
    {'V',31},
    {'W',32},
    {'X',33},
    {'Y',34},
    {'Z',35}
};

string BaseConverter::Converter(string value, int fromBase, int toBase)
{
    if(!GoodValue(value,fromBase))
    {
        return "Improper Value";
    }
    if (fromBase == toBase)
    {
        return value;
    }
    return FromBase10(ToBase10(value,fromBase),toBase);
}
string BaseConverter::Converter(int decValue, int base)
{
    return FromBase10(decValue,base);
} 



bool BaseConverter::GoodValue(string&amp; value, int base)
{
    for(int i = 0; i &lt; value.length();i++)
    {
        value[i] = toupper(value[i]);
        if (values[value[i]]&gt;= base)
        {
            return false;
        }   
    }
    return true;
}

string BaseConverter::FromBase10(int value, int base)
{
    const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string baseValue = "";
    while (value &gt; 0)
    {
        baseValue.insert(baseValue.begin(), chars[value % base]);
        value /= base;
    }
    return baseValue;
}

int BaseConverter::ToBase10(string value, int base)
{
    int decValue = 0;
    int baseMult = 1;
    for (int i = value.size()-1; i &gt; -1; i--)
    {
        decValue += values[value[i]] * baseMult;
        baseMult *= base;
    }
    return decValue;
}


Notice the simplicity of only having to call one wrapper function(string test = BaseConverter::Converter("291", 10, 16);)