Классическая статья о том, как выбирать между элементами и атрибутами, приведена здесь:
http://xml.coverpages.org/elementsAndAttrs.html
Я отмечаю, что в конце страницы он цитирует Джона Коуэна, цитируя меня: «Бегунники всегда задают этот вопрос. Те, у кого небольшой опыт, выражают свое мнение страстно. Эксперты говорят вам, что нет правильного ответа».
На некоторых (особенно старых) платформах (см. Комментарии ниже) вам может потребоваться
#define _USE_MATH_DEFINES
, а затем включить необходимый файл заголовка:
#include <math.h>
, а значение пи может быть доступно через :
M_PI
В моем math.h
(2014) он определен как:
# define M_PI 3.14159265358979323846 /* pi */
, но проверьте свой 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.
*/
Однако:
на новых платформах (по крайней мере, на моем 64-битном Ubuntu 14.04) мне не нужно определять _USE_MATH_DEFINES
На (недавних) платформах Linux есть long double
значения, также предоставленные как расширение GNU:
# define M_PIl 3.141592653589793238462643383279502884L / * pi * /
C++ 20 std::numbers::pi
Наконец, это прибыло: http://eel.is/c++draft/numbers
я ожидаю, что использование будет похоже:
#include <numbers>
#include <iostream>
int main() {
std::cout << std::numbers::pi << std::endl;
}
я дам ему попытку, когда поддержка прибудет в GCC, GCC 9.1.0 с g++-9 -std=c++2a
все еще не поддерживает его.
принятое предложение описывает:
5.0. “Headers” [заголовки] В таблице [tab:cpp.library.headers], новое
<math>
заголовок должен быть добавлен.[...]
namespace std { namespace math { template<typename T > inline constexpr T pi_v = unspecified; inline constexpr double pi = pi_v<double>;
существует также std::numbers::e
, конечно, :-) , Как вычислить Euler константу или Euler, приводимого в действие в C++?
Эти константы используют C++ 14 переменных шаблонных функций: C++ 14 Переменных Шаблонов: какова их цель? Какой-либо пример использования?
В более ранних версиях проекта, константа находилась под std::math::pi
: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdf
Pi можно вычислить как atan (1) * 4
. Вы можете рассчитать значение таким образом и кэшировать его.
Поскольку официальная стандартная библиотека не определяет константу PI, вам придется определить ее самостоятельно. Итак, ответ на ваш вопрос «Как я могу получить PI без определения его вручную?» это «Вы не делаете - или вы полагаетесь на некоторые специфичные для компилятора расширения.». Если вас не беспокоит переносимость, вы можете проверить это в руководстве к вашему компилятору.
C ++ позволяет писать
const double PI = std::atan(1.0)*4;
, но не гарантируется, что инициализация этой константы будет статической. Однако компилятор G ++ обрабатывает эти математические функции как внутренние и может вычислять это постоянное выражение во время компиляции.
Стандартный C ++ не имеет константы для PI.
Многие компиляторы C ++ определяют M_PI
в cmath
(или в math .h
для C) как нестандартное расширение. Возможно, вам придется #define _USE_MATH_DEFINES
, прежде чем вы его увидите.
Вместо того, чтобы писать
#define _USE_MATH_DEFINES
, я бы рекомендовал использовать -D_USE_MATH_DEFINES
или / D_USE_MATH_DEFINES
в зависимости от вашего компилятора.
Таким образом, вы можете быть уверены, что даже в случае, если кто-то включит заголовок до вас (и без #define), у вас все равно будут константы вместо скрытая ошибка компилятора, на отслеживание которой потребуется много времени.
Вы также можете использовать ускорение, которое определяет важные математические константы с максимальной точностью для запрошенного типа (например, float vs double).
const double pi = boost::math::constants::pi<double>();
Дополнительные примеры см. В документации по boost .
Обычно я предпочитаю определять свое собственное: const double PI = 2 * acos (0.0);
, потому что не все реализации предоставляют это для вас.
Вопрос о том, есть ли эта функция вызывается во время выполнения или статически выключается во время компиляции, обычно это не проблема, потому что в любом случае это происходит только один раз.