用C ++计算Ramanujan的常数

时间:2015-07-16 00:02:40

标签: c++ math double

您可以看到Ramanujan's constant 这是我的代码:

#include <iostream>
#include <math.h>
#define _USE_MATH_DEFINES
using namespace std;

int main ()
{
long double s=sqrt(163);
long double P=M_PI;
long double R=exp(s*P);

cout.precision(150);

cout<<"Pi=  "<<P<<"\n"<<"sqrt(163)=  "<<s<<"\n"<<"R=  "<<R;
return(0);
}   

这是我的出局:

Pi=  3.141592653589793115997963468544185161590576171875
sqrt(163)=  12.767145334803704059822848648764193058013916015625
R=  262537412640768256  

我的计划有什么问题?
正确的输出是262537412640768743.99999999999925 ...

2 个答案:

答案 0 :(得分:5)

double约有15 decimal digits of precision

您的计划使用M_PIdoublenot a long double

因此,您的答案大约有15位精确度。

答案 1 :(得分:0)

在编译行中设置long-double选项时,将调用带有Intel C ++的长双精度的80位精度模式。正如您将在英特尔C ++文档中看到的那样,80位长双精度是16字节对齐的,因此sizeof(long double)是16。

所有Windows和Linux x64编译器都将SSE作为默认模式,将所有float和double数据作为SSE数据类型。在Windows x64的早期开发中,禁止使用80位x87数据。在完全发布时放宽了此限制,但缺少Windows库支持。在linux中,长双重支持应该与gcc兼容。

80位长的double将与任何x64编译器具有相同的问题;由于SSE和x87数据之间的转换,具有混合数据类型的表达式float / long double或double / long double可能效率低下。如果gcc选项-mfpmath = 387提供了部分解决方案,那么它将以double和float数据类型的许多常规优化为代价,但icc没有这样的选项。

自:

[IntelSupportForum][1]