Как использовать константу PI в C ++

Классическая статья о том, как выбирать между элементами и атрибутами, приведена здесь:

http://xml.coverpages.org/elementsAndAttrs.html

Я отмечаю, что в конце страницы он цитирует Джона Коуэна, цитируя меня: «Бегунники всегда задают этот вопрос. Те, у кого небольшой опыт, выражают свое мнение страстно. Эксперты говорят вам, что нет правильного ответа».

417
задан Yu Hao 4 April 2014 в 09:08
поделиться

8 ответов

На некоторых (особенно старых) платформах (см. Комментарии ниже) вам может потребоваться

#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.
 */

Однако:

  1. на новых платформах (по крайней мере, на моем 64-битном Ubuntu 14.04) мне не нужно определять _USE_MATH_DEFINES

  2. На (недавних) платформах Linux есть long double значения, также предоставленные как расширение GNU:

     # define M_PIl 3.141592653589793238462643383279502884L / * pi * /
    
502
ответ дан 22 November 2019 в 23:14
поделиться

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

9
ответ дан 22 November 2019 в 23:14
поделиться

Pi можно вычислить как atan (1) * 4 . Вы можете рассчитать значение таким образом и кэшировать его.

164
ответ дан 22 November 2019 в 23:14
поделиться

Поскольку официальная стандартная библиотека не определяет константу PI, вам придется определить ее самостоятельно. Итак, ответ на ваш вопрос «Как я могу получить PI без определения его вручную?» это «Вы не делаете - или вы полагаетесь на некоторые специфичные для компилятора расширения.». Если вас не беспокоит переносимость, вы можете проверить это в руководстве к вашему компилятору.

C ++ позволяет писать

const double PI = std::atan(1.0)*4;

, но не гарантируется, что инициализация этой константы будет статической. Однако компилятор G ++ обрабатывает эти математические функции как внутренние и может вычислять это постоянное выражение во время компиляции.

40
ответ дан 22 November 2019 в 23:14
поделиться

Стандартный C ++ не имеет константы для PI.

Многие компиляторы C ++ определяют M_PI в cmath (или в math .h для C) как нестандартное расширение. Возможно, вам придется #define _USE_MATH_DEFINES , прежде чем вы его увидите.

26
ответ дан 22 November 2019 в 23:14
поделиться

Вместо того, чтобы писать

#define _USE_MATH_DEFINES

, я бы рекомендовал использовать -D_USE_MATH_DEFINES или / D_USE_MATH_DEFINES в зависимости от вашего компилятора.

Таким образом, вы можете быть уверены, что даже в случае, если кто-то включит заголовок до вас (и без #define), у вас все равно будут константы вместо скрытая ошибка компилятора, на отслеживание которой потребуется много времени.

45
ответ дан 22 November 2019 в 23:14
поделиться

Вы также можете использовать ускорение, которое определяет важные математические константы с максимальной точностью для запрошенного типа (например, float vs double).

const double pi = boost::math::constants::pi<double>();

Дополнительные примеры см. В документации по boost .

108
ответ дан 22 November 2019 в 23:14
поделиться

Обычно я предпочитаю определять свое собственное: const double PI = 2 * acos (0.0); , потому что не все реализации предоставляют это для вас.

Вопрос о том, есть ли эта функция вызывается во время выполнения или статически выключается во время компиляции, обычно это не проблема, потому что в любом случае это происходит только один раз.

8
ответ дан 22 November 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: