特定のマシンで仮数の長さを確認するにはどうすればよいですか?
-
20-08-2019 - |
質問
特定のコンピュータの仮数部の桁数と単位の四捨五入を調べたいと考えています。これらが何であるかについては理解していますが、それらを見つける方法がわかりません。ただし、それらがコンピュータごとに異なる可能性があることは理解しています。
この数値は、エラーの分析など、数値分析の特定の側面を実行するために必要です。
私が現在考えていることは、オーバーフローが発生するまで数値をゆっくりとインクリメントする小さな C++ プログラムを作成できることですが、どのタイプの数値を使用すればよいかわかりません。
私は正しい道を進んでいますか?これを正確に計算するにはどうすればよいでしょうか?
解決
私はあなたが使用していたどんな言語が山車が格納された方法を指定するだろうと思うだろう。私は、Javaは、特定のIEEE標準(754、私は思う)を使用することによってこれを行う知っています。
これが指定されていない場合、私はあなただけの実際の数は変わるかどうかを確認するために1から0.5を追加することで、独自のチェックを行うことができると思います。それがない場合は、1に0.25を追加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+」を使用しますので、あなたは、実際に、2ではなく1となるベース番号が必要になる場合があります。
EDITます:
それが明確に4バイトの浮動小数点数を有するシステムのために63ビットを与えるように、上述の方法はいくつかの問題を有することができる表示されます。
は、中間結果(私は明示的なキャスト[while (((float)(a + b) != (float)(a))
]と同じコードので、それを疑う同様の問題を有している)、または(可能性が高い、私は信じて)単位値a
が近いビットで表現することができるという可能性に関係するのかどうか指数を調整することによって、分数b
、私はまだ知らない。
今のところ、それは(その情報が利用可能な場合)私はIEEE754の使用など、上記言語情報に頼るのがベストです。
私は警戒プレーヤーのためのトラップとしてで問題のあるコードを残しておきます。それが妙に動作する理由はたぶん、複数の浮動小数点の知識を持つ人は、私が説明したメモを残すことができます(無推測、してください: - )。
EDIT 2:
このコード片をフロートに格納されている中間体を確実にすることによってそれを固定します。ジョナサン・レフラーは正しかったが判明 - 。それは中間結果だった。
#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)の計算値は、ヘッダーファイル内の1つに一致することを示す。
Cで記述されたけれども、それは任意の言語(情報がヘッダーまたはそれが言語のドキュメントで指定されたということおかげで利用可能でない具体もの)にも適用可能であるべきです。 Eclipseは私のUbuntuボックスに起動するので、時間がかかるので、私は唯一のCでテスト: - 。)
他のヒント
C、および拡張 C++ の場合、情報は次のとおりです。 <float.h>
または <cfloat>
ヘッダー。
C99 の場合、情報は規格のセクション 5.2.4.2.2 にあります。
FLT_RADIX
FLT_MANT_DIG
FLT_DIG
FLT_EPSILON
FLT_MIN_EXP
FLT_MIN
FLT_MIN_10_EXP
FLT_MAX_EXP
FLT_MAX
FLT_MAX_10_EXP
これらのほとんどの DBL および LDBL バリエーションについても同様に ( DBL_RADIX
または LDBL_RADIX
)。この規格は、IEEE 754 (1999 年に現行の IEEE 754 標準の古いバージョン。新しいバージョンは 2008 年に出版されたと思います)。
あなたはC ++ライブラリで<limits>
をチェックアウトする場合があります:
#include <iostream>
#include <limits>
#include <typeinfo>
template <typename T>
void printDetailsFor() {
std::cout
<< "Printing details for " << typeid(T).name() << ":\n"
<< "\tradix: " << std::numeric_limits<T>::radix << "\n"
<< "\tradix digits: " << std::numeric_limits<T>::digits << "\n"
<< "\tepsilon: " << std::numeric_limits<T>::epsilon() << "\n"
<< std::endl;
}
int main() {
printDetailsFor<int>();
printDetailsFor<float>();
printDetailsFor<double>();
printDetailsFor<long double>();
return 0;
}
私はあなたの仮数ビットの数より1以上でなければなりませんstd::numeric_limits<T>::digits
をしたいと思います。私のマシンは、出力します:
Printing details for i:
radix: 2
radix digits: 31
epsilon: 0
Printing details for f:
radix: 2
radix digits: 24
epsilon: 1.19209e-07
Printing details for d:
radix: 2
radix digits: 53
epsilon: 2.22045e-16
Printing details for e:
radix: 2
radix digits: 64
epsilon: 1.0842e-19