long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);
long long int out = A + B*D;
printf("%lld",out);
これにより結果が得られます:-2147483648
理由がわかりません (肯定的な結果である必要があります)。誰か助けてくれませんか?
long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);
long long int out = A + B*D;
printf("%lld",out);
これにより結果が得られます:-2147483648
理由がわかりません (肯定的な結果である必要があります)。誰か助けてくれませんか?
おそらく、これらの定数を「長い長い」リテラルとして指定する必要がありますか? 例えば3289168178315264LL
どのコンパイラ/オペレーティング システムを使用していますか? Windows XP と IT WORKS で Visual C++ 2008 Express Edition を使用してコードを実行しました - 回答: 6578336356630528 (これは 53 ビットの数値なので、double の中にちょうど収まります)。
また、操作の順序が重要かどうかを確認するために、2 つのバリエーションを試しました。
long long int out = A; アウト+=B*D;
long long int out = B*D; アウト+=A;
これらは両方とも機能します!
奇妙。
結果を int フィールド内に格納しているため、コンパイラは最初に "A+B*D" の結果を整数に丸める必要があると思います。基本的に、データ型の競合が発生しています。
A と B はどちらも、長さが 8 バイトの long long int の有効な数値です。それらに 1.000 を掛けても、有効な long long int 値を持つことができます。他のいくつかの言語では、int64 としても知られています。
ただし、double も 64 ビットですが、その一部が指数として使用されます。double を int64 で乗算すると、結果は別の double になります。別の int64 を追加しても、double のままです。次に、特定の丸め方法を使用せずに、結果を再び int64 に割り当てています。コンパイラがこれに 4 ビットの丸め関数を使用しても驚かないでしょう。コンパイラがそのステートメントを吐いたり壊したりしないことにさえ驚いています!
いずれにせよ、このような大きな数を使用する場合、異なるタイプを混在させる場合は特に注意する必要があります。
あなたの答え(確認する必要があります)は正常に計算されますが、符号ビットにオーバーフローが発生し、答えが負になります。解決策 : すべての変数を符号なしにします。
どうして:
数値は、コンピューターのメモリに一連のビットとして格納されます。このようなシリーズの最初のビットが設定されている場合、数値が負であることを意味します。したがって、計算は機能しますが、符号ビットにオーバーフローします。
おすすめ:
これほど大きな数値を扱っている場合は、多精度演算ライブラリを入手することをお勧めします。'T は、多くの時間と手間を省きます。
sqrt へのパラメーターはdoubleである必要があります。
#include <math.h>
double sqrt( double num );
また、結果を B * D から long long に明示的にキャストする必要があります。
long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5.0);
printf("%f\n",D);
long long int out = A + (long long) (B * D);
printf("%lld",out);