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

16進数から10進数の変換 DouKaku?16進数から10進数への変換 - みずぴー日記からですが、一般的に 16 進数から 10 進数への変換は以下のようにして行います。

#! /usr/bin/gawk -f
# hex2dec.awk

BEGIN {
    print hex2dec("0x12437308CCB6");
    print hex2dec("0x2C9C1227FC6520B");
}

function hex2dec(str,   hex, i, x) {
    hex[0] = 0;     hex[1] = 1;     hex[2] = 2;     hex[3] = 3;
    hex[4] = 4;     hex[5] = 5;     hex[6] = 6;     hex[7] = 7;
    hex[8] = 8;     hex[9] = 9;     hex["A"] = 10;  hex["B"] = 11;
    hex["C"] = 12;  hex["D"] = 13;  hex["E"] = 14;  hex["F"] = 15;
    str = substr(str, 3);

    for (i = 1; i <= length(str); i++) {
        x = x * 16 + hex[substr(str, i, 1)];
    }
    return x;
}

実行してみると分かるのですが、0x2C9C1227FC6520B は awk の扱える範囲を越えているようです。

$ nawk -f hex2dec.awk
20080902065334
200904012311450112 <- 正しくは 200904012311450123

こういう場合には MPFR を扱える xgawk の出番です。

#! /usr/bin/gawk -f
# hex2dec.awk

@load mpfr

BEGIN {
    MPFR_MANTISSA = 100;
    MPFR_PRECISION = 100;
    print hex2dec("0x12437308CCB6");
    print hex2dec("0x2C9C1227FC6520B");
}

function hex2dec(str,   hex, i, x) {
    hex[0] = 0;     hex[1] = 1;     hex[2] = 2;     hex[3] = 3;
    hex[4] = 4;     hex[5] = 5;     hex[6] = 6;     hex[7] = 7;
    hex[8] = 8;     hex[9] = 9;     hex["A"] = 10;  hex["B"] = 11;
    hex["C"] = 12;  hex["D"] = 13;  hex["E"] = 14;  hex["F"] = 15;
    str = substr(str, 3);

    x = 0;          # MPFR を使用する場合に必須
    for (i = 1; i <= length(str); i++) {
        x = mpfr_add(mpfr_mul(x, 16), hex[substr(str, i, 1)]);
    }
    return x;
}

どうも MPFR を xgawk で扱う場合に値の代入されていない変数をセロとして扱うことはしないようですので、変数の初期化 (ゼロの代入) が必要になります。 実行結果では、フォーマットは整数で出力されていませんが、正しい値を示しています。

$ xgawk -f hex2dec_mpfr.awk
2.0080902065334000000000000000000E13
2.0090401231145012300000000000000E17

うまく整数化できていませんが、確かに正しい値を示しています。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png