用C++计算Ramanujan常数

Calculate Ramanujan's constant with C++

可以看到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...

一个 double 有大约 15 decimal digits of precision.

您的程序使用 M_PI,即 doublenot a long double

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

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

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

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

发件人:

[IntelSupportForum][1]