2006年10月20日
CPU実験(3)
しかしC言語でfloatと書いても実はdoubleで扱われることがあるのはどうしたものか。printfをはさむとfloatとして扱われるようになるという謎現象も確認。まぁ普通は単精度なんて使わんからねぇ。ビットを変えずに uint -> float に変換する部分がこんな感じになっている。
float gf;
float *gfp;
float uint2float(unsigned int i)
{
cerr << "uint2float: " << i << endl;
unsigned int *ip = &i;
gfp = (float*)ip;
gf = (*gfp);
return gf;
}
cerrを抜くと結果が変わってくる。ちょっとgccの挙動を調べた方がいいな。
ちなみにppm形式はWindowsだとIrfanViewで見れるみたい > IS2006er
HWの方はnaokiさんによりUSBが完動(負荷テストクリア)、yamaさんによりSRAMが動作(本格的な負荷テストはまだ)するようになったらしい。すばらしー。いい感じ。
-----
(2006/10/20)
ポインタを引数に取るような関数を間に挟んだら成功した。
unsigned int float2uintp(float *fp)
{
unsigned int *ip = (unsigned int *)fp;
unsigned int i = (*ip);
return i;
}
float uint2floatp(unsigned int *ip)
{
float *fp = (float*)ip;
float f = (*fp);
return f;
}
unsigned int float2uint(float f)
{
float *fp = &f;
unsigned int i = float2uintp(fp);
return i;
}
float uint2float(unsigned int i)
{
unsigned int *ip = &i;
float f = uint2floatp(ip);
assert(i == float2uint(f));
return f;
}
- by
- at 07:19



comments
浮動小数点数の計算について、レジスタ上では 80 ビットで計算して、メモリに突っ込むときに 32/64 ビットに切り詰めるという Intel 系プロセッサの罠ではないかと思います。前後のプログラムやコンパイラの最適化の具合で、レジスタ上でどれだけ計算をやりくりするかか変わるので、結果が変わってしまうのです
試してませんが、 volatile とか付けるとどうでしょうね