【C++】N進数で表現された数値をM進数に変換する

#背景
競技プログラミング、ちょくちょく進数変換をする機会がありますよね。
2進→10進変換とか16進→2進変換とか、よくある数値ならいいのですが、
たまに中途半端な数字の進数変換を求められることがあります。
そんなときのために、任意の進数から任意の進数へ変換する関数を作りました。
テストは最低限の確認しかしていないので、抜け漏れあるかも。

#使い方
- `#include<string>` が必要です。
- 入力文字列は最大36進数の文字(0〜9,A,B,...,Z)まで対応しています。
- 入力文字列を37進数以上と見なすことも可能です。
- 出力は36進数までの対応です。
- 不正入力に対するエラーは、実装していません。（時間があればやる）

```cpp:2進数の数値"10110011"を10進数に変換する
n_ary("10110011", 2, 10); //出力値：179
```
```cpp:10進数の数値"511"を16進数に変換する
n_ary("511", 10, 16); //出力値：1FF
```
```cpp:36進数の数値"5Z"を10進数に変換する
n_ary("5Z", 36, 10); //出力値：215
```
```cpp:1,000,000進数の数値"5XZ"を10進数に変換する
n_ary("5XZ", 1000000, 10); //出力値：5,000,033,000,035
```
#ソースコード
###メイン処理：string n_ary(string, int, int)
`！自作関数を3つ使用しています。コピペで使用する際は後述のサブルーチンも合わせて使ってください！`

```cpp:n_ary(string,int,int)
/*  関数名          n_ary(string str, int n, int m)
    説明            n 進数で表現された数値を文字列 str で受け取り、m 進数に直して文字列で出力する。
    使用ライブラリ  string
    使用自作関数    ntodec, decton, pow_ll
    制約事項        36進数までの対応。負の値には対応していない。
*/
string n_ary(string str, int n, int m){
    unsigned long tmp = 0;
    string ret;

    for(int i=0; i<str.length(); i++){
        tmp += (unsigned long) ntodec(str[str.length()-1-i]) * pow_ll(n, i);
    }

    if(tmp==0) return "0";
    while(tmp!=0){
        ret = decton(tmp%m) + ret;
        tmp/=m;
    }
    return ret;
}
```

###サブルーチン1：N進→10進変換 (N≦36)
文字 0〜9, A〜Z を 0〜35 の整数に変換する関数です。
<details><summary>クリックでソースコードを表示</summary><div>

```cpp
/*  関数名          ntodec(const char c)
    説明            char で 文字{0,1,2,...,9,A,B,...,Z} を受け取り、
　　　　　　　　　　　 int で {0,1,2,...9,10,11,...,35}に直して返す。
　　　　　　　　　　　 それ以外の文字が来た場合は-1を返す。
    使用ライブラリ   なし
*/
int ntodec(const char c){
    switch(c){
        case '0': return 0;
        case '1': return 1;
        case '2': return 2;
        case '3': return 3;
        case '4': return 4;
        case '5': return 5;
        case '6': return 6;
        case '7': return 7;
        case '8': return 8;
        case '9': return 9;
        case 'A': return 10;
        case 'B': return 11;
        case 'C': return 12;
        case 'D': return 13;
        case 'E': return 14;
        case 'F': return 15;
        case 'G': return 16;
        case 'H': return 17;
        case 'I': return 18;
        case 'J': return 19;
        case 'K': return 20;
        case 'L': return 21;
        case 'M': return 22;
        case 'N': return 23;
        case 'O': return 24;
        case 'P': return 25;
        case 'Q': return 26;
        case 'R': return 27;
        case 'S': return 28;
        case 'T': return 29;
        case 'U': return 30;
        case 'V': return 31;
        case 'W': return 32;
        case 'X': return 33;
        case 'Y': return 34;
        case 'Z': return 35;
        default : return -1;
    }
}
```
</div></details>

###サブルーチン2：10進→N進変換 (N≦36)
0〜35 の整数を文字 0〜9, A〜Z に変換する関数です。
<details><summary>クリックでソースコードを表示</summary><div>

```cpp
/*  関数名          decton(const int n)
    説明            int で 数値 0〜35 を受け取り、文字{0,1,2,...,9,A,B,...,Z}に直して char で返す。
　　　　　　　　　　　 それ以外の数字が来た場合は \0 を返す。
    使用ライブラリ  なし
*/
char decton(const int n){
    switch(n){
        case 0: return '0';
        case 1: return '1';
        case 2: return '2';
        case 3: return '3';
        case 4: return '4';
        case 5: return '5';
        case 6: return '6';
        case 7: return '7';
        case 8: return '8';
        case 9: return '9';
        case 10: return 'A';
        case 11: return 'B';
        case 12: return 'C';
        case 13: return 'D';
        case 14: return 'E';
        case 15: return 'F';
        case 16: return 'G';
        case 17: return 'H';
        case 18: return 'I';
        case 19: return 'J';
        case 20: return 'K';
        case 21: return 'L';
        case 22: return 'M';
        case 23: return 'N';
        case 24: return 'O';
        case 25: return 'P';
        case 26: return 'Q';
        case 27: return 'R';
        case 28: return 'S';
        case 29: return 'T';
        case 30: return 'U';
        case 31: return 'V';
        case 32: return 'W';
        case 33: return 'X';
        case 34: return 'W';
        case 35: return 'Z';
        default : return '\0';
    }
}
```
</div></details>

###サブルーチン3：べき乗計算（long long型）
`long long`で$x^n$を計算します。
`std::pow`で桁数が足りないとき用に作ったものです。
`double`型で事足りる場合は`std::pow`で十分ですので、本関数は必須ではありません。
<details><summary>クリックでソースコードを表示</summary><div>
高速化を狙って`inline`にしてみたり。

```cpp
/*  関数名          pow_ll(long long x, long long n)
    説明            x^n を計算する。long long 対応
    使用ライブラリ  なし
*/
inline long long pow_ll(long long x, long long n){
    long long ret = x;
    if(n==0) return 1;
    for(long long i=1; i<n; i++){
        ret *= x;
    }
    return ret;
}
```
</div></details>

#まとめ
この関数さえ仕込んでおけば、N進数からM進数への変換が簡単に行えると思います。
注意すべき点としては、以下でしょうか。
- 小数に対応していない
- 負の数に対応していない
- 不正入力に対応していない
- 雑なテストしかしていない（ごめんなさい）

ただし不正入力に関しては、`decton()`と`ntodec()`において `0〜9、A〜Z` 以外の入力があった場合に `-1` や `\0` をリターンする仕様になっているのでうまく利用してください。