JDKの元のバイナリ検索アルゴリズムは32ビット整数を使用し、(low + high) > INT_MAX
( http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html )。
(符号付きの)64ビット整数を使用して同じバイナリ検索アルゴリズムを書き換えた場合、low + high
10 ^ 18バイトのメモリを持つことは物理的に不可能であるため、INT64_MAXを超えることはありませんか?
(符号付き)64ビット整数を使用して物理量を表す場合、アンダーフローとオーバーフローが発生しないと想定するのは妥当ですか?
短い答えはノーです。ただし、一部のアプリケーションでは、想定が正しい場合があります。
符号付き整数2 ^ 63を想定します。わかりやすくするためにコンマが追加されています= 9,223,372,036,854,775,808だいたい9 * 10 ^ 18です。 10 ^ 18は「エクサ」です。
ウィキペディアによると 「2013年の時点で、World Wide Webは4ゼタバイトに達していると推定されています。[12]」、つまり4000エクサバイトです。したがって、WWWは2 ^ 63バイトの約400倍です。
したがって、符号付き(または符号なし)64ビット整数よりはるかに大きい物理量が少なくとも1つあります。 単位がバイトであると仮定します。単位がギガバイトのようにはるかに大きい場合、問題はありませんが、測定の精度は低くなります。
別の例として、遠くにある銀河を考えてみましょう。アンドロメダ銀河は実際には近いものの1つであり、2.5 * 10 ^ 6光年離れています。 単位がマイルの場合、64ビットの符号付き整数よりも14.5 * 10 ^ 18になります。さて、明らかにそれはあなたが測定に使用する単位に依存しますが、いくつかの銀河はアンドロメダよりはるかに遠くにあります。 ( 最も遠いものは13 * 10 ^ 9 L.Y.離れています。 )測定に必要な精度によっては、64ビット整数がオーバーフローする可能性があります。
(Added)はい、マイルは天文距離のひどい単位です。より通常の単位は 天文単位 であり、およそ9,300万マイルです。その測定単位を使用すると、最も遠い既知の銀河はおよそ10 ^ 15 A.Uです。 (私の計算が正しい場合)、これは64ビットintに適合します。ただし、月、近くの周回衛星までの距離も測定する場合は、その単位が大きすぎます。
エレクトロニクスのもう1つの例: ファラッド(F)、静電容量の単位 。大きなコンデンサの範囲は最大5kFです。そして、この数は、ハイブリッド車、「スマートグリッド」などが改善するにつれて、時間とともに増加する可能性があります。 10 ^ -18 F程度の小さな静電容量を測定できます。したがって、今日測定できる「実際の」静電容量の全体的な範囲は5 * 10 ^ 21であり、64ビット整数よりも大きくなります。
組合せ論が関与しているときは、宇宙に行く必要さえありません。 2 ^ 95 ブリッジのゲームで可能な取引 があり、それは複雑さの小さな側面にあります。
あなたの質問に最も関連する物理量はコンピューターRAMです。
Windows Server 2012 最大4 TBをサポート 物理メモリ。それは2です42 バイト。 RAM容量が毎年約2倍になっている場合、からわずか17年後「Windows Server 2032」がサポートされます262 物理メモリのバイト、そのときのlow + high
は2に達します63 -2、最大の符号付き64ビット整数にキスします。
64ビットで常に十分であると想定すれば、セーフティクリティカルなシステムが故障しないことを願っています。
もう少し一般的な用途では、最も適切な物理量はメモリアドレススペースです。 (物理メモリよりもはるかに大きなアドレススペースがあると便利です。たとえば、メモリに多くのスタックを配置し、すべてに拡張の余地があります。)現在の x86-64 実装は48ビットの仮想アドレスをサポートしているため、 これらのCPUが2に到達するまでにわずか14年62 バイトアドレス空間の制限。
そして分散共有メモリ "(物理的に分離された)メモリを1つの(論理的に共有された)アドレス空間としてアドレス指定できる場所があります」.
物理量は、オーバーフローまたはアンダーフローなしで64ビット整数で表すことができると想定するのは妥当ですか?
ではない正確に。それより大きくても小さくてもたくさんの数があるので、浮動小数点数があります。浮動小数点数は、精度を下げて範囲を広げます。
あなたが引用した特定の例では、それよりも大きい数が必要になることはほとんどありません。 64ビットはおよそ18千兆の要素に対応します。しかし、決して言うことはありません。
あなたの仮定は、浮動小数点数でしか表現できない物理量を処理しません。そして、たとえばすべての数値に10000を掛けることですべての数値をスケーリングすることを決定した場合でも(値は引き続き整数ですが、10000分の1で表すことができます)、このスキームはゼロに非常に近い数値、たとえば電子の質量に対しては失敗します(9.1094 *10⎻³¹kg)。
これは非常に現実的な(そして非常に小さい)物理量、 ここにいくつかあります で問題が発生します。そして、それが実際の物理量ではないと主張する場合(たとえそれがkgであっても)、次のことを考慮してください。
10 kg (obviously physical quantity)
1 kg (same)
10⎻² kg (1/100 kg, or about 1/3 ounce) (also quite real)
だから、私はこれでどこへ行くのかわかります。最後の1つは処理できません。
もちろん、数値内に特別なフィールドを設定して、可変乗数によって整数部分を拡大または縮小できます。あなたはちょうど浮動小数点を発明しました。
最初に、整数で表すことができる/すべき物理値は何ですか?
整数は、コンピューターシステムの自然数(およびそれらの間の差)の表現であるため、他の何かに適用することは間違っています。したがって、連続領域に属する距離やその他の量を呼び出すことは、議論の余地はありません。そのような数量には実数表現があります。また、いつでも任意の大きさの単位を選択して、任意の値を特定の精度で適合させることができます。
つまり、自然数であり、64ビット整数をオーバーフローできる物理値は何ですか?
2つ考えられます。物理オブジェクト(原子など)の数、および量子システムが取り得るエネルギーレベル。これらは厳密に整数である2つのものです。さて、私はあなたが原子を分割できることを知っていますが、それでも整数の量を生成し、無期限に分割することはできません。 どちらも64ビットの符号なし整数の範囲を簡単に超えることができます。原子の数は多く、1つのatomは複数のエネルギー状態にあることができます。
情報が物理的であるかどうかは非常に議論の余地があります。そうではないと思います。したがって、情報量が物理的なものであるとは言えません。つまり、RAMの量やそのようなものではありません。これを許可すると、今日のテクノロジーで1ビットを格納するために複数のatomが必要になるため、簡単に原子の数がこの数を超えます。
Jerry101の答えに加えて、私はこの非常にシンプルで実用的な正しさのテストを提供したいと思います。
64ビットOSで、malloc
を介してメモリを割り当てるとします。メモリアロケータが、要求したサイズの63番目のビットが設定されている有効なメモリブロックを返すことにしたとしましょう。
言い換えると、0xFFFFFFFFxxxxxxxx
がmalloc
の呼び出しから返される可能性のある正当なメモリ範囲であるプログラミング環境がいくつかあるとします。
問題は、コードが意図したとおりに機能するかどうかです。
同様の状況が32ビットオペレーティングシステムで発生した場合、一部のソフトウェアは、「上半分」にメモリアドレスが指定されていると正しく動作しませんでした。当初、このようなメモリアドレスは特権コード(オペレーティングシステム、デバイスドライバー、および周辺機器のハードウェア)でのみ使用できると考えられていましたが、32ビットのアドレス空間不足のため、OSベンダーはその予約空間の一部を利用できるようにすることにしましたそれを要求するアプリケーション。
幸いなことに、この状況は、少なくとも10年間はしばらくの間、64ビットプログラムで発生することはほとんどありません。
そのような状況が最終的に発生すると、128ビットのアドレス可能なプロセッサとオペレーティングシステムがその時点で主流になり、それらの「レガシーアプリケーション」が動作できる「64ビットエミュレーション環境」を提供できるようになるということです。今日の64ビットオペレーティングシステムと同様の仮定の下で。
最後に、この説明はメモリアドレスにのみ焦点を当てていることに注意してください。特定のタイムスタンプ形式はマイクロ秒に多くの精度のビットを割り当て、その結果、将来の時間を表すために利用できるビットが少なくなるため、タイムスタンプに関する同様の問題はより注意深く行う必要があります。これらの問題は、ウィキペディアの記事 2038年問題 に要約されています。
これは、ケースバイケースで質問する必要がある質問です。あなたすべきではない 64ビット演算がオーバーフローしないという一般的な仮定を使用しています。正しい量がはるかに狭い範囲であっても、悪意のあるデータソースが不当な量を与えて、オーバーフローし、予期せずにこの状況に遭遇するよりも、この状況に備えることをお勧めします。
64ビットの数値がオーバーフローしないことに依存するコードを記述することが理にかなっている場合があります。私が知っている例の主なクラスはカウンターです。カウンターは使用されるたびにインクリメントされます。ナノ秒あたり1インクリメント(実際的ではない)の速度であっても、オーバーフローするのに1世紀以上かかります。
システムの正確さを「障害までの時間」に依存することは、最初は「常に間違っている」ように見えるかもしれませんが、認証/ログインを使用して常時を実行することに注意してください。 (ブルートフォースのために)十分な時間が与えられた場合、そのようなシステム(パスワード、プライベートキー、セッショントークンなどに基づく)は機能しなくなります。
物理量が64ビットに収まらない可能性はありますか?もちろん。他の人たちは、太陽の中の原子の数または次の銀河までのミリメートルの数を数えると指摘しました。そのようなケースがアプリケーションに関連するかどうかは、アプリケーションが何であるかに依存します。倉庫の特定のビンにあるアイテムの数を数える場合は、16ビットで十分です。さまざまな条件を満たす世界の人々の数に関する統計をコンパイルしている場合、数十億を記録できる必要があるため、32ビット以上が必要になります。 37ビットの数値などのサポートが組み込まれています。これが原子のモル数を数える化学アプリケーションである場合、64ビットでは不十分です。
技術的には、今日2 ^ 64バイトのメモリを搭載したコンピューターがないからといって、必ずしも配列のインデックスが2 ^ 64を超えることはありません。 「スパース配列」と呼ばれる概念があり、配列の要素の多くは物理的にどこにも格納されておらず、そのような格納されていない値には、nullやゼロなどのデフォルト値があると見なされます。しかし、配列または何らかのリストを検索する関数を作成していて、配列へのインデックスを保持するために使用しているフィールドのサイズが最大可能アドレスの2倍を超えている場合は、オーバーフローをチェックします。 2つのインデックスを追加する必要はありません。
64ビット整数がすべての数値を保持できると想定するのは不合理です。複数の理由:
64ビット整数の最大値と最小値は有限数です。すべての有限数に対して、より大きいおよびより小さい有限数が存在します。
128ビットと256ビットの数値を使用した計算は、現在さまざまな場所で使用されています。多くのプロセッサには、128ビット整数で動作する特定の命令があります。
20年前、1 GBのディスクは「大容量」と見なされていました。今日、1 TBディスクは小さいと見なされます。 20年前の平均的なデスクトップのRAMは約16 MBでした。現在のデスクトップには16 GBを超えるRAMが搭載されています。ハードディスク容量とRAMは過去に指数関数的に増加しており、将来的には指数関数的に増加すると予測されています。誰かがそれが成長を止めるべきである非常に良い理由を思いつくことができない限り、それが止まると思っても意味がありません。