0

MinGW /GCC4.7.1でWindows7を使用しています。Cで実行しようとしましたが、データ型を変えて何を試しても、正しく印刷されないdouble ans = pow(2,1000)ことがわかりました。ans

しかし、私は(ここでは、実際には、このページの一番下にあります)、同じことをLinuxコンピューターで実行すると、正しく印刷されることを読みました。

MinGWフォルダーのlimits.hファイルにあるchar、int、およびlong longに課せられた制限を認識していますが、doubleとfloatの制限はどこにありますか?これらはOSまたはアーキテクチャごとに異なりますか?

編集:

切り捨てられたゼロで埋められた回答を出力するコードは次のとおりです。

#include <stdio.h>
#include <math.h>

int main(void)
{
   double ans = pow(2,1000);

   printf("%.0f", ans);

   return 0;
}
4

3 に答える 3

6

あなたが尋ねている質問は、あなたが見ている問題とは関係ありません。

使用しているすべてのシステムが、タイプに対して同じ表現double、つまり64ビットIEEE倍精度である可能性が非常に高くなります。

pow(2, 1000)(または、より同等に、より明確に、の値pow(2.0, 1000.0)は2.0 1000です。2の累乗であるため、正確に表すことができますが、大きい数値の相対精度は非常に粗いです。

double値は通常、10進数で約15桁程度の精度です。

どうやら、printfLinuxシステムで使用されるのglibc実装は、値の完全な10進表現を出力しようとしますが、他の実装は、15桁程度の有効printf数字を超える数字の一部またはすべてをゼロに置き換えます。後者はおそらく実装が少し簡単ですが、どちらのアプローチも有効です。

いくつかの異なるシステムでプログラムを実行すると、次の結果が得られます(読みやすくするために行を折りたたんでいます)。

10715086071862673000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000

10715086071862673209484250490600018105614050000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000

10715086071862673209484250490600018105614048117055336074437503883703510511249361
22493198378815695858127594672917553146825187145285692314043598457757469857480393
45677748242309854210746050623711418779541821530464749835819412673987675591655439
46077062914571196477686542167660429831652624386837205668069376

最後はたまたま21000に正確等しくなります。

印刷する数は非常に大きく正確に表現できるという点で珍しいものです。glibcは、正確に印刷するために余分な労力を費やしています。しかし、より一般的には、浮動小数点値は不正確になる傾向があり、最初の数桁を超える数字について心配する価値はほとんどありません。

たとえば、を正確に表すpow(2.0, 1000.0) + 1.0 ことはできません。計算しようとすると、おそらくとまったく同じ結果が得られpow(2.0, 1000.0)ます。

于 2012-07-11T00:03:27.047 に答える
3

のサイズとはfloatdouble 実装によって異なる場合があります。

、、、、の保証と同様に、が、より小さくなることはなく、-より小さくdoubleなるfloatことlong doubleはありません。doublelong longlongintshort

于 2012-07-10T23:07:44.873 に答える
3

はい、floatやdoubleなどのタイプの実装は、プラットフォームごとに異なる可能性があります。

ただし、最も一般的な最新のプラットフォームでは、浮動小数点型の標準であるIEEE754が使用されています。したがって、通常とは異なるプラットフォームを使用していない限り、これらのタイプの1つのバイナリ表現が異なる可能性はほとんどありません。

あなたが言及した他のスレッドは、印刷ルーチンの精度の潜在的な違いを強調しているようです。これは、表現が異なる(またはサイズが異なる)という意味ではありません。

于 2012-07-10T23:08:05.423 に答える