问题 最佳平台独立pi常量?


我知道你可以使用:

#define _USE_MATH_DEFINES

接着:

M_PI

获得恒定的pi。但是,如果我没记错的话(欢迎评论)这是依赖于编译器/平台的。那么,使用pi常量最可靠的方法是什么,当我将它从Linux移植到其他系统时不会导致任何问题?

我知道我可以定义一个float / double然后自己将它设置为舍入的pi值,但我真的想知道是否有指定的机制。


4995
2018-02-18 23:16


起源

如果它是依赖于平台的,那么每个平台都应该为这些宏提供适当的值,不是吗? - Pointy
一世 认为 唯一真正独立于平台的方式是 atan(1.0)*4.0。 - Nicu Stiurca
它应该,但它呢? ;) - Draugr


答案:


会议C ++ 有一篇关于生成pi的不同选项的文章: C ++&π 他们讨论了一些选项 CMATH,这不是平台独立的:

double pi = M_PI;
std::cout << pi << std::endl;

促进

std::cout << boost::math::constants::pi<double>() << std::endl

和使用 晒黑,与 constexpr 因为SchighSchagh指出不是平台无关的:

 double const_pi() { return std::atan(1)*4; }

我把所有的方法都收集到了一个 实例

#include <iostream>
#include <cmath>
#include <boost/math/constants/constants.hpp>

double piFunc() { return std::atan(1)*4; }

int main()
{
    double pi = M_PI;
    std::cout << pi << std::endl;
    std::cout << boost::math::constants::pi<double>() << std::endl ;
    std::cout << piFunc() << std::endl;
}

11
2018-02-18 23:22



@SchighSchagh公平点,更新答案。 - Shafik Yaghmour
谢谢,我认为这足以满足我的需求。我会考虑集成boost,因为我想尝试其他一些功能,无论如何。 - Draugr
@Draugr你可以随时尝试使用一些提升 在线C ++编译器 可用,我在我的回答中添加了一个实例。 - Shafik Yaghmour
@SchighSchagh看 它是一个符合标准的编译器扩展,将非constexpr标准库函数视为constexpr吗? 更多细节。 - Shafik Yaghmour


下面的函数计算pi而不依赖于任何库。

此外,其结果的类型是模板参数。

平台ueber独立性有点窒息,因​​为它只适用于固定精度小数类型 - 计算值需要收敛并在2次迭代中保持不变。

因此,如果指定某种任意精度的有理或浮点类,它将根据需要自动增加其精度,对此函数的调用将不会很好地结束。

#include <iostream>
#include <iomanip>

namespace golf {
    template <typename T> inline T calc_pi() {
        T sum=T(0), k8=T(0), fac=T(1);
        for(;;) {
            const T next = 
                sum + fac*(T(4)/(k8+T(1))-T(2)/(k8+T(4))-T(1)/(k8+T(5))-T(1)/(k8+T(6)));
            if(sum == next) return sum;
            sum=next;
            fac /= T(16);
            k8  += T(8);
    }   }
    static const auto PI = calc_pi<double>();
}

int main() {
    std::cout << std::setprecision(16) << golf::PI << std::endl;
    return 0;
}

3
2018-02-19 01:39



非常感谢这个,模板集成是一个非常好的主意。 - Draugr