5

次のことを考慮してください。

#include <iostream>
#include <cmath>
int main()
{
  using std::cout;
  using std::endl;

  const long double be2 = std::log(2);
  cout << std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
      << endl;

  cout << std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
      << endl;
}

出力

  3, 2
  3, 3

なぜ出力が異なるのですか?ここで何が欠けていますか?

また、ここにコードパッドへのリンクがあります:http: //codepad.org/baLtYrmy

そして、それが重要な場合は、Linuxでgcc4.5を使用しています。

4

3 に答える 3

4

これを追加すると:

cout.precision(40);

私はこの出力を取得します:

2.999999999999999839754918906642444653698, 2
3.00000000000000010039712117215771058909, 3

3.0に非常に近いが、正確には等しくない2つの値を出力しています。非常に近い値では結果が異なる可能性があるのはその性質ですstd::floor(数学的には、不連続関数です)。

于 2011-08-11T19:39:45.487 に答える
2
#include <iostream>
#include <cmath>
#include <iomanip>

int main()
{
  using std::cout;
  using std::endl;

  const long double be2 = std::log(2);

  cout << setprecision (50)<<std::log(8.0)<<"\n";
  cout << setprecision (50)<<std::log(8.0L)<<"\n";
  cout << setprecision (50)<<std::log(8.0) / be2 << ", " << std::floor(std::log(8.0) / be2)
       << endl;
  cout << setprecision (50)<< std::log(8.0L) / be2 << ", " << std::floor(std::log(8.0L) / be2)
       << endl;

  return 0;
}

出力は次のとおりです。

2.0794415416798357476579894864698871970176696777344
2.0794415416798359282860714225549259026593063026667
2.9999999999999998397549189066424446536984760314226, 2
3.0000000000000001003971211721577105890901293605566, 3

ここで出力を確認すると、2つの出力の精度にわずかな違いがあることがわかります。これらの丸め誤差は通常、実行中にここでfloat&doubleの操作を開始しfloor()、表示される結果は、本来あるべきと感じるものではありません。

浮動小数点数または倍数を使用する場合は、PrecisionRoundingの2つの属性を覚えておくことが重要です。

あなたはここで私の答えでそれについてもっと読みたいかもしれません、同じ理由がここにも当てはまります。

于 2011-08-11T19:32:14.007 に答える
2

アルスが言っていることを拡張するには-

最初のケースでは、8バイトの倍精度値を16バイトの長さの倍精度値で除算しています。2番目のケースでは、16バイト長のdoubleを16バイト長のdoubleで除算しています。これにより、非常に小さな丸め誤差が発生します。これは、次のように表示されます。

cout << std::setprecision(20) << (std::log(8.0) / be2) << std::endl;
cout << std::setprecision(20) << (std::log(8.0L) / be2) << std::endl;

これにより、次のようになります。

2.9999999999999998398
3.0000000000000001004

編集して言う:この場合、sizeofはあなたの友達です(精度の違いを確認するため):

sizeof(std::log(8.0));  // 8
sizeof(std::log(8.0L)); // 16
sizeof(be2);            // 16
于 2011-08-11T19:38:30.867 に答える