6

long double に関する情報を検索してみましたが、これまでのところ、コンパイラによって実装が異なることがわかりました。

Ubuntu (XUbuntu) Linux 12.10 で GCC を使用すると、次のようになります。

double PId = acos(-1);
long double PIl = acos(-1);
std::cout.precision(100);

std::cout << "PId " << sizeof(double) << " : " << PId << std::endl;
std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;

出力:

PId 8  : 3.141592653589793115997963468544185161590576171875
PIl 16 : 3.141592653589793115997963468544185161590576171875

彼らが(ほぼ)同じものを出力する理由を誰でも理解していますか?

4

3 に答える 3

8

acos のリファレンスによると、long doublea を渡した場合にのみa を返しますlong doublestd::acosまた、ヒヒが提案したように使用する必要があります。これは私のために働く:

#include <cmath>
#include <iostream>

int main() {

  double PId = acos((double)-1);
  long double PIl = std::acos(-1.0l);
  std::cout.precision(100);

  std::cout << "PId " << sizeof(double) << " :  " << PId << std::endl;
  std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
}

出力:

PId 8  : 3.141592653589793115997963468544185161590576171875
PIl 12 : 3.14159265358979323851280895940618620443274267017841339111328125

         3.14159265358979323846264338327950288419716939937510582097494459

最後の行は出力の一部ではなく、この精度の pi の正しい数字が含まれています。

于 2012-12-16T17:44:05.090 に答える
5

正しい有効桁数を取得するには、 を使用しますstd::numeric_limits。C++11 ではdigits10、10 進数の有効桁数 (が有効なビットdigitsを与えるのとは対照的に) があります。

#include <cmath>
#include <iostream>
#include <limits>

int
main()
{
  std::cout.precision(std::numeric_limits<float>::digits10);
  double PIf = acos(-1.0F);
  std::cout << "PIf " << sizeof(float) << " :  " << PIf << std::endl;

  std::cout.precision(std::numeric_limits<double>::digits10);
  double PId = acos(-1.0);
  std::cout << "PId " << sizeof(double) << " :  " << PId << std::endl;

  std::cout.precision(std::numeric_limits<long double>::digits10);
  long double PIl = std::acos(-1.0L);
  std::cout << "PIl " << sizeof(long double)  << " : " << PIl << std::endl;
}

x86_64 Linux では次のようになります。

PIf 4 :  3.14159
PId 8 :  3.14159265358979
PIl 16 : 3.14159265358979324
于 2012-12-16T18:25:50.210 に答える
4

試す:

long double PIl = std::acos(-1.0L);

これにより、変換される int だけでなく、long double を渡すことができます。

とにかく、これらの数字のほとんどすべてがゴミであることに注意してください。8 バイトの double を使用すると、数値を実際の PI と比較すると、15 の数値の精度が得られます。

3.1415926535897932384626433

最初の 15 個の数字だけが適合することがわかります。

コメントに記載されているように、実装では 80 ビット表現のみを使用する可能性があり、仮数用に予約するビット数に依存するため、おそらく 2 倍の精度は得られません。

于 2012-12-16T17:43:31.787 に答える