问题
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