アーキテクチャに依存しない方法で浮動小数点数のサイズ (ビット単位) と範囲を見つける方法についての提案を探しています。コードは、さまざまなフラグを使用してさまざまなプラットフォーム (AIX、Linux、HPUX、VMS、おそらく Windoze) でビルドできるため、結果は異なるはずです。符号は、私は 1 ビットしか見ていませんが、指数と仮数のサイズをどのように測定するのですか?
5 に答える
多数のシステムのビルドを検討しているため、コンパイルに GCC を使用することを検討している可能性があります。
浮動小数点に関するいくつかの良い情報 - これはほとんどすべての現代のアーキテクチャが使用するものです: http://en.wikipedia.org/wiki/IEEE_754
これは、発生する可能性のあるいくつかの違いを詳しく説明してい ます http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html
で定義されている値を見てくださいfloat.h
。これらは、必要な値を提供するはずです。
以前のコメントで提案されたリンクをたどると、おそらくWhat Every Computer Scientist Should Know About Floating Point Arithmeticへの参照が表示されるでしょう。ぜひ、時間をかけてこの論文をお読みください。浮動小数点が議論されるとき、どこでもポップアップします。
見つけるのは比較的簡単です:
10 進数または 2 進数。
myfloat a = 2.0,
b = 0.0;
for (int i=0; i<20; i++)
b += 0.1;
(a == b) => decimal, else binary
理由: すべてのバイナリ システムは 2.0 を表すことができますが、バイナリ システムには 0.1 を表すエラー タームがあります。累積することで、この誤差項が丸めのように消えないことを確認できます。たとえば、バイナリ システムでも 1.0 == 3.0*(1.0/3.0) です。
仮数の長さ:
Myfloat a = 1.0,
b = 1.0,
c,
inc = 1.0;
int mantissabits = 0;
do {
mantissabits++;
inc *= 0.5; // effectively shift to the right
c = b+inc;
} while (a != c);
仮数の容量に達するまで、減少項を追加しています。float の場合は 24 ビット、double の場合は 53 ビットが返されますが、これは正しいです (仮数自体には 23/52 ビットしか含まれていませんが、正規化された値では最初のビットが常に 1 であるため、余分なビットが隠されています)。
指数の長さ:
Myfloat a = 1.0;
int max = 0,
min = 0;
while (true) {
a *= 2.0;
if (a != NaN && a != Infinity && whatever) // depends on system
max++;
else
break;
}
a = 1.0;
while (true) {
a *= 0.5;
if (a != 0.0)
min--;
else
break;
}
上または下に当たるまで、左または右に 1.0 シフトしています。通常、exp 範囲は-(max+1) - max
です。
min
が より小さい場合、-(max+1)
(float と double が持つように) サブノーマルがあります。通常、正と負の値は対称ですが (おそらく 1 つのオフセットがあります)、負の値を追加してテストを調整できます。
各フィールドを浮動小数点数で格納するために使用されるビット数は変わりません。
Sign Exponent Fraction Bias
Single Precision 1 [31] 8 [30-23] 23 [22-00] 127
Double Precision 1 [63] 11 [62-52] 52 [51-00] 1023
編集:ジョナサンがコメントで指摘したように、私はlong double型を省略しました。そのビット分解は、読者の演習として残しておきます。:)