4

c++ pow(2,1000) は double の場合は通常大きいですが、機能しています。なぜ?

だから私は数週間C++を学んでいますが、データ型はまだ私を混乱させています.

最初に小さなマイナーなことを 1 つ: 0xbadc0de が別のスレッドに投稿したコードが機能していません。まず第一に私にpow(2,1000)与えますthis more than once instance of overloaded function "pow" matches the argument list.

変更して修正しましたpow(2,1000)->pow(2.0,1000) 問題ないようです、実行してこれを取得します:

http://i.stack.imgur.com/bbRat.png

それ以外の

10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

多くの値が欠落しています。何が原因でしょうか?

しかし、ここで本当の問題です。どうすれば 302 桁の数字が倍精度 (8 バイト) に収まるのだろうか? 0xFFFFFFFFFFFFFFFF = 18446744073709551616 では、どうすればそれよりも大きな数値になるのでしょうか?

浮動小数点数のエンコーディングと関係があると思います。また、0xFFFFFFFFFFFFFFFF でない場合、8 バイトに格納できる最大の数は何ですか?

4

5 に答える 5

8

2^64 ~ 10^208 バイトには 64 ビットの情報が含まれているため、これらのビットを使用して一意のアイテムを格納できます。0これらの項目は、 からまでの整数として簡単に解釈できます2^64 - 1。したがって、10 進数の 302 桁を 8 バイトに格納することはできません。0との間のほとんどの数は、10^303 - 1そのように表現できません。

浮動小数点数は、10 進数 302 桁の数値の近似値を保持できます。これは、仮数と指数を別々に格納するためです。この表現の数値は、特定の有効桁数 (私の記憶が正しければ倍精度の場合は 15 ~ 16) と指数 (メモリ サーブの数百になる可能性があります) を格納します。ただし、10 進数の長さが X バイトの場合、異なる値しか区別できませ2^(8X)ん... 10 進数 302 桁の整数を正確に表すには十分ではありません。

このような数値を表すには、さらに多くのビット (実際には約 1000、または 125 バイト) を使用する必要があります。

于 2013-01-28T17:07:42.483 に答える
1

理由から「浮動小数点」と呼ばれます。データ型には、標準的な意味での数値と、小数点がどこに属するかを示す指数が含まれます。それがpow(2.0, 1000)機能する理由であり、多くのゼロが表示される理由です。浮動小数点数 (または倍精度浮動小数点数よりも大きい倍精度浮動小数点数) には、精度の桁数が固定されています。残りの桁はすべてゼロになります。試してみるpow(2.0, -1000)と、同じ状況が逆に表示されます。

float (32 ビット) の精度の 10 進数の桁数は約 7 で、double (64 ビット) の場合は約 16 桁です。

最近のほとんどのシステムはIEEE 浮動小数点を使用しており、それについての非常に優れた説明にリンクしました。また、特定の標準IEEE 754-1985に関する記事では、さまざまなサイズの浮動小数点数のビット レイアウトについて詳しく説明しています。

于 2013-01-28T17:06:24.087 に答える
1

2.0 ^ 1000 は、数学的には 10 進数 (非浮動) の出力になります。IEEE 浮動小数点数、およびあなたの場合は double (pow 関数が double を取り込んで double を出力するため) には、仮数に割り当てられた 64 ビット表現の 52 ビットがあります。計算すると、2^52 = 4,503,599,627,370,496 です。浮動小数点数は正数と負数を表すことができるため、実際の整数表現は ~ 2^51 = 2,251,799,813,685,248 になります。16 桁あることに注意してください。表示される出力には、16 個の品質 (ゼロ以外) の数字があります。

基本的に、pow 関数は累乗を実行しますが、累乗が ~2^51 を超えると、精度が失われ始めます。最終的には、10 進数の上位 16 桁までの精度が保持されますが、他のすべての桁は保証されません。

したがって、これは浮動小数点の精度/丸めの問題です。

厳密に符号なし整数ランドにいる場合、数値は (2^64 - 1) = 18,446,744,073,709,551,616 の後にオーバーフローします。オーバーフローとは、提供された数値よりも実際に数値が高くなることは決してないということです。実際、この操作からの答えは0になると思います。答えが 2^64 を超えると、結果レジスタはゼロになり、乗算のあとがきは 0 * 2 になり、結果は常に 0 になります。試してみる必要があります。

多精度ライブラリを使用する標準的なコンピューターを使用して、正確な答え (表示されているとおり) を取得できます。これらが行うことは、複数の小さなデータ型を連結することによってより大きなビット コンピューターをエミュレートし、アルゴリズムを使用してオンザフライで変換および印刷することです。Mathematica は、任意精度の数学計算ライブラリを実装する数学エンジンの一例です。

于 2013-01-28T17:17:39.793 に答える
1

浮動小数点型は、同じサイズの整数型よりもはるかに広い範囲をカバーできますが、精度は低くなります。

それらは次のように数値を表します。

  • 正または負を示す符号ビット。 s
  • mantissam1 から 2 の間の値で、特定のビット数の精度を示します。
  • 数値の位取りを示す指数 e

値自体は として計算されm * pow(2,e)、符号ビットが設定されている場合は否定されます。

標準doubleには 53 ビットの仮数部があり、10 進数で約 16 桁の精度が得られます。

したがって、(たとえば) 64 ビットを超える精度で整数を表す必要がある場合、64 ビット整数も 64 ビット浮動小数点型も機能しません。使用している値を表すために必要な数のビットを持つ大きな整数型、または (解決している問題に応じて) 素因数分解などの他の表現が必要になります。そのような型は標準 C++ では使用できないため、独自に作成する必要があります。

于 2013-01-28T17:10:48.353 に答える
1

数バイトで保持できる桁数の範囲を計算すると、(2^(64bits - 1bit)) から (2^(64bits - 1bit) - 1) となります。

変数の左端の桁は符号 (+ と -) を表すためです。したがって、数値の負側の範囲は (2^(64bits - 1bit)) であり、数値の正側の範囲は (2^(64bits - 1bit) - 1) である必要があります。 0 のため正の範囲です (両側で 0 を数えるという評判を避けるため)。

たとえば、64 ビットを計算している場合、範囲は ==> およそ [-9.223372e+18] から [9.223372e+18] になります。

于 2013-08-23T22:07:53.413 に答える