Eta*_*tan 437 c++ trigonometry
我想在一些C++程序中使用PI常量和三角函数.我得到了三角函数include <math.h>.但是,此头文件中似乎没有PI的定义.
如何在不手动定义PI的情况下获取PI?
Fer*_*eak 502
在某些(特别是较旧的)平台上(请参阅下面的评论),您可能需要
#define _USE_MATH_DEFINES
Run Code Online (Sandbox Code Playgroud)
然后包含必要的头文件:
#include <math.h>
Run Code Online (Sandbox Code Playgroud)
pi的值可以通过以下方式访问:
M_PI
Run Code Online (Sandbox Code Playgroud)
在我math.h(2014年)中,它被定义为:
# define M_PI 3.14159265358979323846 /* pi */
Run Code Online (Sandbox Code Playgroud)
但请检查你math.h的更多.来自"旧"的摘录math.h(2009年):
/* Define _USE_MATH_DEFINES before including math.h to expose these macro
* definitions for common math constants. These are placed under an #ifdef
* since these commonly-defined names are not part of the C/C++ standards.
*/
Run Code Online (Sandbox Code Playgroud)
然而:
在较新的平台上(至少在我的64位Ubuntu 14.04上)我不需要定义 _USE_MATH_DEFINES
在(最近的)Linux平台上,还有long double作为GNU扩展提供的值:
# define M_PIl 3.141592653589793238462643383279502884L /* pi */
Run Code Online (Sandbox Code Playgroud)Kon*_*man 164
Pi可以计算为atan(1)*4.你可以用这种方式计算值并缓存它.
Bus*_*icK 108
您还可以使用boost,它为所请求的类型定义了具有最大精度的重要数学常量(即float vs double).
const double pi = boost::math::constants::pi<double>();
Run Code Online (Sandbox Code Playgroud)
查看增强文档以获取更多示例.
小智 74
从芯片上的FPU单元获取它:
double get_PI()
{
double pi;
__asm
{
fldpi
fstp pi
}
return pi;
}
double PI = get_PI();
Run Code Online (Sandbox Code Playgroud)
小智 47
我建议只需输入pi即可获得所需的精度.这将不会为您的执行增加计算时间,并且它可以在不使用任何标头或#defines的情况下移植.计算acos或atan总是比使用预先计算的值更昂贵.
const double PI =3.141592653589793238463;
const float PI_F=3.14159265358979f;
Run Code Online (Sandbox Code Playgroud)
Mat*_* M. 45
而不是写作
#define _USE_MATH_DEFINES
Run Code Online (Sandbox Code Playgroud)
我建议使用-D_USE_MATH_DEFINES或/D_USE_MATH_DEFINES取决于您的编译器.
通过这种方式,您可以确保即使在您执行之前包含标题的人(并且没有#define),您仍将拥有常量,而不是一个模糊的编译器错误,您需要花费很长时间才能跟踪.
sel*_*tze 40
由于官方标准库没有定义常量PI,因此您必须自己定义它.所以你的问题的答案是"如何在不手动定义PI的情况下获得PI?" 是"你没有 - 或者你依赖于一些特定于编译器的扩展." 如果您不关心可移植性,可以查看编译器的手册.
C++允许你写
const double PI = std::atan(1.0)*4;
Run Code Online (Sandbox Code Playgroud)
但是这个常量的初始化并不保证是静态的.然而,G ++编译器将这些数学函数作为内在函数处理,并且能够在编译时计算此常量表达式.
小智 30
The <math.h> header shall provide for the following constants. The
values are of type double and are accurate within the precision of the
double type.
M_PI Value of pi
M_PI_2 Value of pi/2
M_PI_4 Value of pi/4
M_1_PI Value of 1/pi
M_2_PI Value of 2/pi
M_2_SQRTPI
Value of 2/ sqrt pi
Run Code Online (Sandbox Code Playgroud)
Ric*_*dle 26
标准C++没有PI的常量.
许多C++编译器定义M_PI中cmath(或在math.h为C)作为非标准扩展.您可能必须#define _USE_MATH_DEFINES先看到它.
0xb*_*00d 15
我会做
template<typename T>
T const pi = std::acos(-T(1));
Run Code Online (Sandbox Code Playgroud)
要么
template<typename T>
T const pi = std::arg(-std::log(T(2)));
Run Code Online (Sandbox Code Playgroud)
我不会 输入π到你需要的精度.那甚至应该是什么意思?在你需要的精度是精度T,但我们并不知道T.
你可能会说:你在说什么?T将是float,double或long double.所以,只需键入精度long double,即
template<typename T>
T const pi = static_cast<T>(/* long double precision ? */);
Run Code Online (Sandbox Code Playgroud)
但是你真的知道未来标准中不会有新的浮点类型,其精度甚至高于long double?你没有.
这就是为什么第一个解决方案很漂亮的原因.您可以确定该标准会使新类型的三角函数超载.
并且,请不要说在初始化时对三角函数的评估是性能损失.
Joh*_*ane 12
在 C++20 标准库中,\xcf\x80 定义std::numbers::pi_v为float,double和long double,例如
#include <numbers>\nauto n = std::numbers::pi_v<float>;\nRun Code Online (Sandbox Code Playgroud)\n并且可以专门用于用户定义的类型。
\nCir*_*四事件 11
C ++ 20 std::numbers::pi
最后,它到达了:http : //eel.is/c++draft/numbers
我希望用法是这样的:
#include <numbers>
#include <iostream>
int main() {
std::cout << std::numbers::pi << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当GCC支持到达时,我会尝试一下,GCC 9.1.0 g++-9 -std=c++2a仍然不支持它。
接受的提案描述:
5.0。“标题” [headers]在表[tab:cpp.library.headers]中,
<math>需要添加新的标题。[...]
Run Code Online (Sandbox Code Playgroud)namespace std { namespace math { template<typename T > inline constexpr T pi_v = unspecified; inline constexpr double pi = pi_v<double>;
std::numbers::e当然也有一个:-) 如何在C ++中计算欧拉常数或欧拉函数?
这些常量使用C ++ 14变量模板功能:C ++ 14变量模板:它们的用途是什么?有用法示例吗?
在该草案的早期版本中,该常量位于std::math::pi:http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdf
我通常更喜欢定义自己的:const double PI = 2*acos(0.0);因为并非所有实现都为您提供.
是否在运行时调用此函数或在编译时静态调出此函数的问题通常不是问题,因为它只会发生一次.
我在项目中的一个常见标题中使用了以下内容:
#define _USE_MATH_DEFINES
#include <cmath>
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#ifndef M_PIl
#define M_PIl (3.14159265358979323846264338327950288)
#endif
Run Code Online (Sandbox Code Playgroud)
另外,如果包含,下面的所有编译器都会定义M_PI和M_PIl常量<cmath>.不需要添加`#define _USE_MATH_DEFINES,这只是VC++所必需的.
x86 GCC 4.4+
ARM GCC 4.5+
x86 Clang 3.0+
Run Code Online (Sandbox Code Playgroud)
小智 7
我刚刚看到Danny Kalev 撰写的这篇文章,它对C++ 14及以上版本提出了很好的建议.
template<typename T>
constexpr T pi = T(3.1415926535897932385);
Run Code Online (Sandbox Code Playgroud)
我觉得这很酷(虽然我会尽可能使用最高精度的PI),特别是因为模板可以根据类型使用它.
template<typename T>
T circular_area(T r) {
return pi<T> * r * r;
}
double darea= circular_area(5.5);//uses pi<double>
float farea= circular_area(5.5f);//uses pi<float>
Run Code Online (Sandbox Code Playgroud)
一些优雅的解决方案。我怀疑三角函数的精度是否等于类型的精度。对于那些喜欢写一个常量值的人,这适用于 g++ :-
template<class T>
class X {
public:
static constexpr T PI = (T) 3.14159265358979323846264338327950288419\
71693993751058209749445923078164062862089986280348253421170679821480865132823066\
47093844609550582231725359408128481117450284102701938521105559644622948954930381\
964428810975665933446128475648233786783165271201909145648566923460;
...
}
Run Code Online (Sandbox Code Playgroud)
对于任何未来的 long long long double 类型,256 位十进制数字的精度应该足够了。如果需要更多,请访问https://www.piday.org/million/。
| 归档时间: |
|
| 查看次数: |
984029 次 |
| 最近记录: |