Implementation of type “long double” with GCC and C++11

若如初见. 提交于 2020-01-03 09:42:14

问题


I've tried searching for information on long double, and so far I understand it is implemented differently by compilers.

When using GCC on Ubuntu (XUbuntu) Linux 12.10 I get this:

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;

Output:

PId 8  : 3.141592653589793115997963468544185161590576171875
PIl 16 : 3.141592653589793115997963468544185161590576171875

Anyone understand why they output (almost) the same thing?


回答1:


To get the correct number of significant digits use std::numeric_limits. In C++11 we have digits10 for decimal significant digits (as opposed to digits which gives significant bits).

#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;
}

On x86_64 linux I get:

PIf 4 :  3.14159
PId 8 :  3.14159265358979
PIl 16 : 3.14159265358979324



回答2:


According to the reference of acos, it will return a long double only if you pass a long double to it. You'll also have to use std::acos like baboon suggested. This works for me:

#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;
}

Output:

PId 8  : 3.141592653589793115997963468544185161590576171875
PIl 12 : 3.14159265358979323851280895940618620443274267017841339111328125

         3.14159265358979323846264338327950288419716939937510582097494459

The last line is not part of the output and contains the correct digits for pi to this precision.




回答3:


Try:

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

That makes you pass a long double and not just an int which gets converted.

Note that mostly all of these numbers are rubbish anyway. With an 8 byte double you get 15 Numbers of precision, if you compare your numbers with the real PI

3.1415926535897932384626433

You see that only the first 15 Numbers fit.

As noted in the comments, you probably won't get double the precision as the implementation might only use a 80Bit representation and then it depends on how many bits it reserves for the mantissa.



来源:https://stackoverflow.com/questions/13903785/implementation-of-type-long-double-with-gcc-and-c11

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!