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

Я хочу использовать константу PI и тригонометрические функции в некоторой программе на C ++. Я получаю тригонометрические функции с include . Однако в этом заголовочном файле не существует определения для PI.

Как я могу получить PI, не определяя его вручную?

    17 Solutions collect form web for “Как использовать константу PI в C ++”

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

     #define _USE_MATH_DEFINES 

    а затем включить необходимый файл заголовка:

     #include  

    и значение pi можно получить через:

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

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

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

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

    Посмотрите дополнительную документацию для большего количества примеров.

    Получите это от блока FPU на чипе вместо этого:

     double get_PI() { double pi; __asm { fldpi fstp pi } return pi; } double PI = get_PI(); 

    Я бы порекомендовал просто набирать в pi нужную вам точность. Это не добавило бы никакого времени вычисления к вашему исполнению, и оно было бы переносимым без использования каких-либо заголовков или #defines. Вычисление acos или atan всегда дороже, чем использование предварительно рассчитанного значения.

     const double PI =3.141592653589793238463; const float PI_F=3.14159265358979f; 

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

     #define _USE_MATH_DEFINES 

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

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

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

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

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

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

    На странице пользователя Posix math.h :

      The  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 

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

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

    я бы сделал

     template T const pi = std::acos(-T(1)); 

    или

     template T const pi = std::arg(-std::log(T(2))); 

    Я бы не набрал в π точной точности . Что это значит? Точность, в которой вы нуждаетесь, – это точность T , но мы ничего не знаем о T

    Вы могли бы сказать: о чем вы говорите? T будет float , double или long double . Итак, просто введите точность long double , т. Е.

     template T const pi = static_cast(/* long double precision π */); 

    Но знаете ли вы, что в будущем в стандарте не будет нового типа с плавающей точкой с еще большей точностью, чем long double ? Вы этого не сделаете.

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

    И, пожалуйста, не говорите, что оценка тригонометрической функции при инициализации является штрафом за производительность.

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

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

    Я использую следующее в одном из моих общих заголовков в проекте, который охватывает все базы:

     #define _USE_MATH_DEFINES #include  #ifndef M_PI #define M_PI (3.14159265358979323846) #endif #ifndef M_PIl #define M_PIl (3.14159265358979323846264338327950288) #endif 

    С другой стороны, все нижеперечисленные компиляторы определяют константы M_PI и M_PIl, если вы включаете . Нет необходимости добавлять `#define _USE_MATH_DEFINES, что требуется только для VC ++.

     x86 GCC 4.4+ ARM GCC 4.5+ x86 Clang 3.0+ 

    Я просто наткнулся на эту статью Дэнни Калева, у которой есть большой совет для C ++ 14 и выше.

     template constexpr T pi = T(3.1415926535897932385); 

    Я думал, что это довольно круто (хотя я бы использовал максимальную точность PI там, где мог), особенно потому, что шаблоны могут использовать его на основе типа.

     template T circular_area(T r) { return pi * r * r; } double darea= circular_area(5.5);//uses pi float farea= circular_area(5.5f);//uses pi 

    В windowsх (cygwin + g ++) я нашел необходимым добавить флаг -D_XOPEN_SOURCE=500 для препроцессора для обработки определения M_PI в M_PI

    C ++ 14 позволяет делать static constexpr auto pi = acos(-1);

    Вы можете сделать это:

     #include  #ifndef M_PI #define M_PI (3.14159265358979323846) #endif 

    Если M_PI уже определен в cmath , это не будет делать ничего, кроме include cmath . Если M_PI не определен (что, например, в Visual Studio), он определит его. В обоих случаях вы можете использовать M_PI для получения значения pi.

    Это значение pi происходит от qmath.h Qt Creator.

    Значения, такие как M_PI, M_PI_2, M_PI_4 и т. Д., Не являются стандартными C ++, поэтому constexpr кажется лучшим решением. Можно сформулировать различные выражения const, которые вычисляют один и тот же pi, и это касается меня, обеспечивают ли они (все) полную точность. В стандарте C ++ явно не упоминается, как вычислить pi. Поэтому я склоняюсь к определению pi вручную. Я хотел бы поделиться решением ниже, которое полностью поддерживает все виды долей pi.

     #include  #include  template constexpr double dpipart() { long double const pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899863; return static_cast(pi * RATIO::num / RATIO::den); } int main() { std::cout < < dpipart>() < < std::endl; } 
    Давайте будем гением компьютера.