doubleに格納できる最大の整数


回答:


506

精度を失うことなくdoubleに格納できる最大/最大の整数は、doubleの可能な最大値と同じです。つまり、DBL_MAX約1.8×10 308(doubleがIEEE 754 64ビットdoubleの場合)です。整数です。正確に表現されています。もう何が欲しいですか?

続けて、最大の整数とは何かを尋ねてください。その整数とそれより小さい整数すべて、精度を失うことなくIEEE 64ビットdoubleに格納できます。IEEE 64ビットdoubleの仮数は52ビットなので、2 53だと思います。

  • 2 53 + 1は、最初の1と最後の1の間にゼロが多すぎるため、格納できません。
  • 2 53未満のもの仮数部に52ビットが明示的に格納されたが格納され、実際には指数が別の指数を与えます。
  • 2 53は明らかに2のべき乗なので、保存できます。

または別の見方:バイアスが指数から外され、質問とは無関係である符号ビットを無視すると、倍精度浮動小数点数によって格納される値は、2のべき乗に2を乗じた52ビット整数です。指数− 52。したがって、指数52を使用すると、2 52から2 53  − 1 までのすべての値を格納できます。次に、指数53を使用すると、2 53の後に格納できる次の数値は2 53 + 1×2 53 − 52です。したがって、精度の損失は最初に2 53 + 1で発生します。


126
+1問題は、質問が実際には質問者がおそらく意図したものを意味しておらず、両方の回答を提供していないことに気づいた(「技術的に正しい」と「おそらく期待される」)。
Pascal Cuoq 09

62
または、私はそれらを呼び出す傾向があるので、「いじり」と「助けようとする」:-)
スティーブ・ジェソップ

8
私はトニー・ザ・ポニーに頭を下げ、他には頭を下げません。
スティーブジェソップ

11
「すべての小さい整数」を意味するのではなく、大きさが等しいか小さいすべての整数を意味します。2 ^ 53未満の負の整数がたくさんあり、doubleで正確に表すことができないためです。
サザンホスピタリティ

13
私はより小さいことを意味します、そして私がより小さいと言うとき、それはまさに私が意味することです:-) -1,000,000は1未満ですが、それは小さくありません。
スティーブジェソップ

77

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

7
それは「近い」が2 ^ N未満であると仮定すると、より速いテストでdouble dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);同じ結果が得られます
Seph

4
@セフ何...?番号?while (dbl == --dbl)永久にループするか、まったくループしません。:)(この場合、2 ^ Nなので、まったくありません)。下からアプローチする必要があります。実際には、期待される結果よりも1つ少なくなります(whileループの1つのチェックでdblが減少するため)。そして、左側の評価の前または後にデクリメントが行われるかどうかは、実行順序に依存します(これは、私の知る限りでは未定義です)。前者の場合、それは常に真であり、永久にループします。
falstro 2016年

10
2 ^ 53 = 9,007,199,254,740,992がどこかにあることを示しているのかもしれません。
Xonatron、2017年

1
これと議論するのは難しいです!素敵な実験
MattM、

での使用の弱点は、数学を使用while (dbl + 1 != dbl) dbl++;してdbl + 1 != dbl評価することをlong double検討してくださいFLT_EVAL_METHOD == 2。これは、無限ループで終了する可能性があります。
chux-モニカを復活させる'25年

25

ウィキペディアは、IEEE 754へのリンクと同じコンテキストでこれを言う必要があります。

典型的なコンピューターシステムでは、「倍精度」(64ビット)の2進浮動小数点数は、係数が53ビット(そのうちの1つが暗示されます)、11ビットの指数、および1つの符号ビットです。

2 ^ 53は9 * 10 ^ 15を少し超えています。


@スティーブジェソップ多かれ少なかれ、それは確かに私が言っていることです。IEEEに準拠する必要があるFPUを持たないハードウェアシステムにも遭遇したため、8か月後にここに戻って同じ情報が必要な場合、「一般的なシステム」は役に立たない私の68Kベースのマイクロコントローラー(FPUがないと仮定すると...思い出せません)。
San Jacinto、

14
@サンジャシント-「これは役に立たない」は過度に厳しいです。答えは非常に役に立ちますが、典型的なコンピューターシステムが実際にIEEE 754表現を使用しているというコメントが含まれている場合ほど有用ではありません。
スティーブンC.スティール

@Stephen C. Steel、実際にはあなたは正しい。私のシナリオでは、後でこれに戻ってIEEE maxを探していますが、「典型的なシステム」とは何かについてはあいまいなところがありますが、この苦情以外にも答えにはメリットがあります。
San Jacinto

20

IEEE 754 double(64ビット)で表すことができる最大の整数は、その値自体が整数であるため、型が表すことができる最大の値と同じです。

これはで表され0x7FEFFFFFFFFFFFFF、次の要素で構成されています。

  • 符号ビット1(負)ではなく0(正)
  • (2047がa または無限大を示す0x7FE)ではなく、最大指数(2046はバイアスを差し引いた後の1023を表す)。0x7FFNaN
  • 0xFFFFFFFFFFFFFすべてが52ビットの最大仮数。

バイナリでは、値は暗黙的な1に続いて仮数からの別の52の1であり、次に指数からの971ゼロ(1023-52 = 971)です。

正確な10進値は次のとおりです。

17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955863276687817154045895351438246423432132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334827479782620414264881258612586125862141258612671258612586125861258612586125861258612691265812648125861265812648125861258612658126581265812658586848184829400

これは約1.8 x 10 308です。


それと0の間のすべての値で連続的に表現できる最大値についてはどうですか?
アーロンフランケ

@AaronFranke質問は連続した表現については質問しませんでしたが、その別の質問への回答は、他のほとんどの回答に含まれているか、実際の回答として誤って与えられています。2⁵³(2の53乗)です。
Simon Biber

8

仮数のサイズを確認する必要があります。IEEE 754 64ビット浮動小数点数(52ビットに1が含まれている)は、2 ^ 53以下の絶対値を持つ整数を正確に表すことができます。


8
2 ^ 53も正確に表すことができます:-)
スティーブジェソップ

6

2
この回答は、引用を使用するとはるかに良くなります。
San Jacinto

2
@Carlよく、整数の左側にゼロがある場合、それは正確に格納されます。
Wilhelm、

4
@ダウンボーター全員:1.7976931348623157×10 ^ 308 正確な整数です。あなたは皆、数学の補習クラスか何かに出席する必要がありますか?
ダン成形

6
この絶望的に沈められた答えの議論において、私たちはここで意味論に取りかかっています。確かに、その数は正確に表すことができ、それによって質問の文字を満たします。しかし、それがニアミスの海にある正確な小さな島であることは誰もが知っています。ほとんどの人は、「精度がドレインを下回る最大数」を意味する質問を正しく内挿しました。ああ、CompSciが正確な科学であることは素晴らしいことではないでしょうか。:)
Carl Smotricz、2009

2
@DanMoulding 1.7976931348623157×10 ^ 308は正確な整数ですが、この特定の整数をdoubleに正確に格納できないことは確かです。
Pascal Cuoq 2014

2

DECIMAL_DIGfrom <float.h>は、少なくともその妥当な近似を与えるはずです。これは10進数を扱い、実際には2進数で格納されるため、おそらく精度を失うことなく少し大きいものを格納することができますが、正確にはどれほど難しいかはわかりません。あなたはそれをFLT_RADIXとから理解できるはずDBL_MANT_DIGですが、その結果を完全に信頼できるかどうかはわかりません。


これは質問に対する答えを提供しません。批評したり、著者に説明を求めるには、投稿の下にコメントを残してください。
MichaelChirico 2015

@MichaelChirico:これは、回答が書かれたときに存在していたので、彼が尋ねようとした質問に答えます。質問の編集履歴を表示するには、質問の下部にある「編集されたJun 19 '14 at 11:40」リンクをクリックします。
Jerry Coffin

あなたの回答は、回答が持つべき自信/信頼性に欠けているように見えるため、コメントのように読みます(「少なくとも妥当なものを与えるべきです...」「正確にどれだけ...言うのは難しい」 ")。質問や回答について専門知識がないため、間違っている可能性があります。私がレビューキューからここに送られた場合、2セントを投入するだけです(これは、他のユーザーがあなたの回答にフラグを付けたことを意味します)。
MichaelChirico 2015

1
@MichaelChirico:彼らはそうかもしれません-あなたは主題を知らない唯一の人から遠く離れています。あなたが異常なのは、あなたがそれを知らないことに気づいていることです。Cの浮動小数点数の精度について信頼できると思われるほとんどの答えは、単に誤っています。たとえば、上記の多く(ほとんど)はdouble、aが特定のIEEEタイプに直接対応するという誤った仮定に基づいていますが、これは必須ではなく、この回答が書かれたとき、質問は特定のIEEEタイプについても言及していませんでした。
Jerry Coffin

とった。その情報を回答に追加することをお勧めします。
MichaelChirico 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.