【C++】進数変換まとめ【2進数、10進数、16進数、float】

C++

こんにちは、コウキです。

前回はPythonで進数変換を行う方法を紹介しましたが、今回はC++バージョンです。
Pythonバージョンはこちら。
【Python】進数変換まとめ【2進数、10進数、16進数、float】

C++では変換の関数が用意されてなかったりするので、少し大変です。
それでは、いってみましょう!!

16進数 ↔ 2進数

16進数から2進数への変換

いきなりゴリ押しですね。
これより良い方法が思いつきませんでした。

std::string htob(const std::string& hex) {
    std::string bin;
    for(int i=0; i<hex.length(); i++){
        if (hex[i] == '0') bin += "0000";
        else if (hex[i] == '1') bin += "0001";
        else if (hex[i] == '2') bin += "0010";
        else if (hex[i] == '3') bin += "0011";
        else if (hex[i] == '4') bin += "0100";
        else if (hex[i] == '5') bin += "0101";
        else if (hex[i] == '6') bin += "0110";
        else if (hex[i] == '7') bin += "0111";
        else if (hex[i] == '8') bin += "1000";
        else if (hex[i] == '9') bin += "1001";
        else if (hex[i] == 'A' || hex[i] == 'a') bin += "1010";
        else if (hex[i] == 'B' || hex[i] == 'b') bin += "1011";
        else if (hex[i] == 'C' || hex[i] == 'c') bin += "1100";
        else if (hex[i] == 'D' || hex[i] == 'd') bin += "1101";
        else if (hex[i] == 'E' || hex[i] == 'e') bin += "1110";
        else if (hex[i] == 'F' || hex[i] == 'f') bin += "1111";
    }
    return bin;
}

2進数から16進数への変換

逆も同じですね。

std::string btoh(const std::string& bin) {
    std::string hex;
    std::string bin4;
    int len = bin.length();
    // 2進数の文字数が4で割り切れるように先頭に0を足す
    std::string tmp;
    if (len % 4 != 0) {
        for (int i = 0; i < 4 -(len % 4); i++) {
            tmp += "0";
        }
    }
    std::string bin_tmp = tmp + bin;
    for (int i=0; i<bin_tmp.length(); i+=4) {
        bin4 = bin_tmp.substr(i, 4);
        if (bin4 == "0000") hex += "0";
        else if (bin4 == "0001") hex += "1";
        else if (bin4 == "0010") hex += "2";
        else if (bin4 == "0011") hex += "3";
        else if (bin4 == "0100") hex += "4";
        else if (bin4 == "0101") hex += "5";
        else if (bin4 == "0110") hex += "6";
        else if (bin4 == "0111") hex += "7";
        else if (bin4 == "1000") hex += "8";
        else if (bin4 == "1001") hex += "9";
        else if (bin4 == "1010") hex += "A";
        else if (bin4 == "1011") hex += "B";
        else if (bin4 == "1100") hex += "C";
        else if (bin4 == "1101") hex += "D";
        else if (bin4 == "1110") hex += "E";
        else if (bin4 == "1111") hex += "F";
    }
    return hex;
}

10進数 ↔ 16進数

10進数から16進数への変換

難しそうに見えますが、文字の長さをそろえているだけで、実際にはsprintfだけで変換できます。
sizeを指定しない場合はそのままの長さで返すようにしています。

std::string itoh(int x, int size = 0) {
    char hex_buf[16];
    sprintf(hex_buf, "%X", x);
    std::string hex_str = hex_buf;
    if (size == 0) {
        return hex_str;
    }
    std::string front;
    if (x >= 0) front = "0";
    else front = "F";
    // 指定のサイズになるまで文字を増やす
    int diff = size - hex_str.length();
    for (int i=0; i < diff; i++){
        hex_str = front + hex_str;
    }
    // 指定のサイズになるまで文字を減らす
    if (diff < 0) {
        hex_str.erase(0, -diff);
    }
    return hex_str;
}

16進数から符号なし10進数への変換

これはそのまま標準の関数が使えます。

unsigned int htoui(const std::string& hex) {
    return strtoul(hex.c_str(), NULL, 16);
}

16進数から符号あり10進数への変換

符号でパターンを分けています。

int htoi(const std::string& hex) {
    int result;
    if (strtoul(hex.substr(0,1).c_str(), NULL, 16) > 7){
        result = strtoul(hex.c_str(), NULL, 16) - 2 * std::pow(2.0, (int)(hex.size() - 1));
    }
    else{
        result = strtoul(hex.c_str(), NULL, 16);
    }
    return result;
}

10進数 ↔ 2進数

10進数から2進数への変換

一度16進数になおしてから、2進数へ変換しています。

std::string itob(int x, int size = 0) {
    std::string bin_str;
    bin_str = htob(itoh(x, ceil(size / 4.0)));
    if (size == 0) {
        return bin_str;
    }
    // サイズ調整
    int diff = size - bin_str.length();
    if (diff < 0) {
        bin_str.erase(0, -diff);
    }
    return bin_str;
}

2進数から符号なし10進数への変換

2進数から符号なし10進数への変換です。

unsigned int btoui(const std::string& bin) {
    return strtoul(bin.c_str(), NULL, 2);
}

2進数から符号あり10進数への変換

int btoi(const std::string& bin) {
    int result;
    if (bin[0] == '1') {
        result = strtoul(bin.c_str(), NULL, 2) - 2 * std::pow(2.0, (int)(bin.size() - 1));
    }
    else{
        result = strtoul(bin.c_str(), NULL, 2);
    }
    return result;
}

float ↔ 16進数

この変換をする前に、事前にint型とfloat型の共用体を定義しておきます。

union intfloat {
    int ival;
    float fval;
};

floatから16進数への変換

先程の共用体にfloatで代入してintで取り出しています。
整数にしたあとはそのまま16進数に変換するだけですね。

std::string ftoh(float input_float) {
    IntFloat value;
    value.fval = input_float;
    std::string result = itoh(value.ival, 8);
    return result;
}

16進数からfloatへの変換

16進数からfloatの変換です。
やっていることはさっきの逆で16進数から10進数に変換して、共用体にintで代入し、floatで取り出します。

float htof(const std::string& hex) {
    IntFloat value;
    value.ival = htoi(hex);
    return value.fval;
}

最後に

今回はC++でいろいろな進数変換をまとめてみました。

進数変換はPythonよりもC++のほうが使う場面が多いかもしれませんね。
それでは^^

コメント

タイトルとURLをコピーしました