好き勝手に・げーあにん?

ファミコンと同い年の社会人ヌルオタの日記

浮動小数点数の2進数表示

ときどきの雑記帖 i戦士篇さん経由で。

浮動小数を2進表記せよ。

浮動小数点数 - Wikipediaを見ると、指数部はちょっと面倒そうなので略。

ロベールのC++入門講座 - ボクノス

union 使えば ALL OK?

#include <stdio.h>

typedef unsigned long long u64;
typedef double f64;

void hoge(double d)
{
    union {
        f64 d;
        u64 ll;
    } u;
    u.d = d;
    printf("\n*** hoge(%f) ***\n", u.d);
    printf("%llx\n", u.ll);

    for (int i = 63; i >= 0; i--) {
        int b = (u.ll >> i) & 0x1;
        if (i == 63) {
            printf("%s", (b == 0 ? "+": "-"));
        } else {
            printf("%d", b);
        }

        if (i == 52) {
            printf(".");
        }
    }
    printf("\n");
}

int main()
{
    printf("sizeof(f64): %d\n", sizeof(f64));
    printf("sizeof(u64): %d\n", sizeof(u64));

    hoge(1.0);
    hoge(-2.0);
    hoge(1.0/3.0);
    hoge(1.0/0.0);
    hoge(-1.0/0.0);
    hoge(0.1);
    hoge(-0.1);

    return 0;
}
出力
sizeof(f64): 8
sizeof(u64): 8

*** hoge(1.000000) ***
3ff0000000000000
+01111111111.0000000000000000000000000000000000000000000000000000

*** hoge(-2.000000) ***
c000000000000000
-10000000000.0000000000000000000000000000000000000000000000000000

*** hoge(0.333333) ***
3fd5555555555555
+01111111101.0101010101010101010101010101010101010101010101010101

*** hoge(inf) ***
7ff0000000000000
+11111111111.0000000000000000000000000000000000000000000000000000

*** hoge(-inf) ***
fff0000000000000
-11111111111.0000000000000000000000000000000000000000000000000000

*** hoge(0.100000) ***
3fb999999999999a
+01111111011.1001100110011001100110011001100110011001100110011010

*** hoge(-0.100000) ***
bfb999999999999a
-01111111011.1001100110011001100110011001100110011001100110011010

g++ 3.4.4 の Cygwin 版で確認。環境依存とかは知らん(投げやり)。

16進数で見れてたら、2進数いらないか?と思いつつ。浮動小数の一部を確実に取得するなら、他の演算を極力使わず、ビット演算だけでとってくるのが確実だと思うとです。

Wikipediaの倍精度の16進表示の例とあってるから、たぶん大丈夫。

ポインタ使っても良かったんですが、union はこういう時に使ってあげないと、出番が無いのでw