使用している言語が何であれ、フロートの格納方法を指定すると思います。Javaが特定のIEEE標準(754だと思います)を使用してこれを行うことは知っています。
指定されていない場合は、0.5 に 1 を追加して、実際の数値が変化するかどうかを確認するだけで、独自のチェックを行うことができると思います。そうであれば、0.25 を 1 に、0.125 を 1 に、というように数値が変化しなくなるまで追加します。次のようになります。
float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
bits = bits + 1;
b = b / 2;
}
仮数ビットが 3 ビットしかない場合、1 + 1/16 は 1 になります。
次に、仮数ビットを使い果たしました。
IEEE754 は最初に暗黙の '1+' を使用するため、基数を 1 ではなく 2 にする必要があるかもしれません。
編集:
上記の方法には、明らかに 4 バイトの浮動小数点があるシステムに 63 ビットが与えられるため、いくつかの問題があるようです。
それが中間結果に関係しているかどうか(明示的なキャスト [ while (((float)(a + b) != (float)(a))
] を使用した同じコードには同様の問題があるため、疑わしい)または(より可能性が高いと思います)単位値を調整することによりa
、小数に近いビットで表現できる可能性があります。b
指数、まだわかりません。
今のところ、IEEE754 の使用など、上記の言語情報に依存するのが最善です (その情報が利用可能な場合)。
問題のあるコードは、用心深いプレイヤーの罠として残しておきます。たぶん、浮動小数点の知識が豊富な人なら、それが奇妙に動作する理由を説明するメモを残すことができます (推測はしないでください:-)。
編集2:
このコードは、中間体が float に格納されるようにすることで問題を修正します。Jonathan Leffler が正しかったことが判明しました - それは中間結果でした。
#include <stdio.h>
#include <float.h>
int main(void) {
float a = 1;
float b = 0.5;
float c = a + b;
int bits = 1;
while (c != a) {
bits = bits + 1;
b = b / 2;
c = a + b;
}
printf("%d\n",FLT_MANT_DIG);
printf("%d\n",bits);
return 0;
}
このコードは (24,24) を出力して、計算された値がヘッダー ファイルの値と一致することを示します。
C で書かれていますが、どの言語にも適用できるはずです (特に、情報がヘッダーで利用できない場合、または言語ドキュメントで指定されているため)。私のUbuntuボックスではEclipseの起動に時間がかかるため、Cでのみテストしました:-)。