精度を失うことなくIEEE 754 double型に格納できる最大の「浮動」整数は何ですか?
精度を失うことなくIEEE 754 double型に格納できる最大の「浮動」整数は何ですか?
回答:
精度を失うことなくdoubleに格納できる最大/最大の整数は、doubleの可能な最大値と同じです。つまり、DBL_MAX
約1.8×10 308(doubleがIEEE 754 64ビットdoubleの場合)です。整数です。正確に表現されています。もう何が欲しいですか?
続けて、最大の整数とは何かを尋ねてください。その整数とそれより小さい整数はすべて、精度を失うことなくIEEE 64ビットdoubleに格納できます。IEEE 64ビットdoubleの仮数は52ビットなので、2 53だと思います。
または別の見方:バイアスが指数から外され、質問とは無関係である符号ビットを無視すると、倍精度浮動小数点数によって格納される値は、2のべき乗に2を乗じた52ビット整数です。指数− 52。したがって、指数52を使用すると、2 52から2 53 − 1 までのすべての値を格納できます。次に、指数53を使用すると、2 53の後に格納できる次の数値は2 53 + 1×2 53 − 52です。したがって、精度の損失は最初に2 53 + 1で発生します。
9007199254740992(9,007,199,254,740,992)は保証なし:)
プログラム
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
結果
9007199254740991 9007199254740992 9007199254740992
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
同じ結果が得られます
while (dbl == --dbl)
永久にループするか、まったくループしません。:)(この場合、2 ^ Nなので、まったくありません)。下からアプローチする必要があります。実際には、期待される結果よりも1つ少なくなります(whileループの1つのチェックでdblが減少するため)。そして、左側の評価の前または後にデクリメントが行われるかどうかは、実行順序に依存します(これは、私の知る限りでは未定義です)。前者の場合、それは常に真であり、永久にループします。
while (dbl + 1 != dbl) dbl++;
してdbl + 1 != dbl
評価することをlong double
検討してくださいFLT_EVAL_METHOD == 2
。これは、無限ループで終了する可能性があります。
ウィキペディアは、IEEE 754へのリンクと同じコンテキストでこれを言う必要があります。
典型的なコンピューターシステムでは、「倍精度」(64ビット)の2進浮動小数点数は、係数が53ビット(そのうちの1つが暗示されます)、11ビットの指数、および1つの符号ビットです。
2 ^ 53は9 * 10 ^ 15を少し超えています。
IEEE 754 double(64ビット)で表すことができる最大の整数は、その値自体が整数であるため、型が表すことができる最大の値と同じです。
これはで表され0x7FEFFFFFFFFFFFFF
、次の要素で構成されています。
0x7FE
)ではなく、最大指数(2046はバイアスを差し引いた後の1023を表す)。0x7FF
NaN
0xFFFFFFFFFFFFF
すべてが52ビットの最大仮数。バイナリでは、値は暗黙的な1に続いて仮数からの別の52の1であり、次に指数からの971ゼロ(1023-52 = 971)です。
正確な10進値は次のとおりです。
17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955863276687817154045895351438246423432132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334827479782620414264881258612586125862141258612671258612586125861258612586125861258612691265812648125861265812648125861258612658126581265812658586848184829400
これは約1.8 x 10 308です。
仮数のサイズを確認する必要があります。IEEE 754 64ビット浮動小数点数(52ビットに1が含まれている)は、2 ^ 53以下の絶対値を持つ整数を正確に表すことができます。
1.7976931348623157×10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
from <float.h>
は、少なくともその妥当な近似を与えるはずです。これは10進数を扱い、実際には2進数で格納されるため、おそらく精度を失うことなく少し大きいものを格納することができますが、正確にはどれほど難しいかはわかりません。あなたはそれをFLT_RADIX
とから理解できるはずDBL_MANT_DIG
ですが、その結果を完全に信頼できるかどうかはわかりません。
double
、aが特定のIEEEタイプに直接対応するという誤った仮定に基づいていますが、これは必須ではなく、この回答が書かれたとき、質問は特定のIEEEタイプについても言及していませんでした。