Я хочу использовать константу PI и тригонометрические функции в некоторых программах на C ++. Я получаю тригонометрические функции с include <math.h>
. Однако в этом заголовочном файле, похоже, нет определения для PI.
Как я могу получить PI, не определяя его вручную?
c++
trigonometry
Этан
источник
источник
3.14
,3.141592
иatan(1) * 4
?Ответы:
На некоторых (особенно старых) платформах (см. Комментарии ниже) вам может понадобиться
и затем включите необходимый заголовочный файл:
и значение пи можно получить через:
По моему
math.h
(2014) это определяется как:но проверьте свой
math.h
на больше. Выписка из "старого"math.h
(в 2009 году):Однако:
на более новых платформах (по крайней мере, на моей 64-битной Ubuntu 14.04) мне не нужно определять
_USE_MATH_DEFINES
На (недавних) платформах Linux есть также
long double
значения, предоставляемые как расширение GNU:источник
#define _USE_MATH_DEFINES
с последующим#include <math.h>
определениемM_PI
в Visual C ++. Спасибо.cmath
вместоmath.h
._USE_MATH_DEFINES
если GCC жалуется, это потому, что__STRICT_ANSI__
он определен (возможно, вы прошли-pedantic
или-std=c++11
), который неM_PI
может быть определен, следовательно, не определите его-D__STRICT_ANSI__
. Когда вы определяете это сами, так как это C ++, а не макрос, вы должны это сделатьconstexpr auto M_PI = 3.14159265358979323846;
.Пи можно рассчитать как
atan(1)*4
. Вы можете рассчитать значение таким образом и кэшировать его.источник
constexpr double pi() { return std::atan(1)*4; }
atan(1)*4 == 3.141592653589793238462643383279502884
(грубо говоря). Я бы не стал ставить на это. Будьте нормальными и используйте необработанный литерал для определения константы. Зачем терять точность, когда вам это не нужно?atan2(0, -1);
.atan
нетconstexpr
.acos(-1)
вместо этого, не нужноatan2
.Вы также можете использовать boost, который определяет важные математические константы с максимальной точностью для запрошенного типа (т. Е. Float против double).
Проверьте дополнительную документацию для дополнительных примеров.
источник
not gonna use libs
мнение - вредитель и, вероятно, причина номер один для плохого программного обеспечения, написанного на C ++.Получите это от блока FPU на чипе вместо этого:
источник
Я бы порекомендовал просто набирать пи с нужной вам точностью. Это не добавит времени на вычисление и будет переносимым без использования заголовков или #defines. Расчет acos или atan всегда обходится дороже, чем использование предварительно рассчитанного значения.
источник
const
aconstexpr
.constexpr
.Вместо того чтобы писать
Я бы порекомендовал использовать
-D_USE_MATH_DEFINES
или в/D_USE_MATH_DEFINES
зависимости от вашего компилятора.Таким образом, вы уверены, что даже в случае, если кто-то включит заголовок перед вами (и без #define), у вас останутся константы, а не неясная ошибка компилятора, которую вы будете искать целую вечность.
источник
<cmath>
в разных местах, это станет большой болью (особенно если он включен другой библиотекой, в которую вы входите). Было бы намного лучше, если бы они поместили эту часть за пределы охраны заголовка, но сейчас ничего не поделаешь. Директива компилятора работает довольно хорошо.Поскольку официальная стандартная библиотека не определяет константу PI, вам придется определить ее самостоятельно. Итак, ответ на ваш вопрос "Как я могу получить PI, не определяя его вручную?" это «Вы не - или вы полагаетесь на некоторые специфичные для компилятора расширения». Если вы не беспокоитесь о переносимости, вы можете проверить руководство вашего компилятора для этого.
C ++ позволяет писать
но инициализация этой константы не гарантируется быть статической. Однако компилятор G ++ обрабатывает эти математические функции как встроенные и способен вычислять это константное выражение во время компиляции.
источник
4*atan(1.)
:atan
его легко реализовать, а умножение на 4 - точная операция. Конечно, современные компиляторы складывают (стремятся сложить) все константы с требуемой точностью, и совершенно разумно использоватьacos(-1)
или даже то,std::abs(std::arg(std::complex<double>(-1.,0.)))
что противоположно формуле Эйлера, и, таким образом, более эстетично, чем кажется (я добавил,abs
потому что я не не помню, как сложная плоскость разрезается или определяется ли она вообще).Со страницы руководства Posix по математике :
источник
C ++ 20
std::numbers::pi
Наконец-то пришло: http://eel.is/c++draft/numbers
Я ожидаю, что использование будет как:
Я попробую, когда поддержка придет в GCC, GCC 9.1.0
g++-9 -std=c++2a
все еще не поддерживает его.Принятое предложение описывает:
Существует также,
std::numbers::e
конечно :-) Как рассчитать постоянную Эйлера или питание Эйлера в C ++?Эти константы используют функцию шаблонов переменных C ++ 14: Шаблоны переменных C ++ 14: какова их цель? Любой пример использования?
В более ранних версиях проекта константа находилась под
std::math::pi
: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdfисточник
Стандарт C ++ не имеет константы для PI.
Многие компиляторы C ++ определяют
M_PI
вcmath
(или вmath.h
C) нестандартное расширение. Возможно, вам придется,#define _USE_MATH_DEFINES
прежде чем вы сможете увидеть это.источник
я бы сделал
или
Я бы не стал вводить π с той точностью, которая вам нужна . Что это вообще должно означать? Точность вам нужно это точность
T
, но мы ничего не знаем оT
.Вы можете сказать: о чем ты говоришь?
T
будетfloat
,double
илиlong double
. Итак, просто введите точностьlong double
, т.е.Но знаете ли вы, что в будущем в стандарте не будет нового типа с плавающей запятой с еще большей точностью, чем
long double
? Вы неИ именно поэтому первое решение красиво. Вы можете быть совершенно уверены, что стандарт перегружает тригонометрические функции для нового типа.
И, пожалуйста, не говорите, что оценка тригонометрической функции при инициализации является ухудшением производительности.
источник
arg(log(x)) == π
для всех0 < x < 1
.Я использую следующее в одном из моих общих заголовков в проекте, который охватывает все основы:
Напомним, что все приведенные ниже компиляторы определяют константы M_PI и M_PIl, если вы включаете их
<cmath>
. Нет необходимости добавлять `#define _USE_MATH_DEFINES, что требуется только для VC ++.источник
M_PI
без необходимости_USE_MATH_DEFINES
Я обычно предпочитаю определять свое собственное:
const double PI = 2*acos(0.0);
потому что не все реализации предоставляют его вам.Вопрос о том, вызывается ли эта функция во время выполнения или является статическим во время компиляции, обычно не является проблемой, потому что в любом случае это происходит только один раз.
источник
double x = pi * 1.5;
и тому подобное). Если вы когда-нибудь намереваетесь использовать PI в хрустящей математике в замкнутых циклах, вам лучше убедиться, что это значение известно компилятору.Я просто наткнулся на эту статью по Danny Kalev , который имеет большой наконечник для C ++ 14 и выше.
Я подумал, что это довольно круто (хотя я бы использовал там PI с наивысшей точностью), особенно потому, что шаблоны могут использовать его в зависимости от типа.
источник
Такие значения, как M_PI, M_PI_2, M_PI_4 и т. Д. Не являются стандартными C ++, поэтому constexpr кажется лучшим решением. Могут быть сформулированы различные выражения const, которые вычисляют один и тот же пи, и меня интересует, обеспечивают ли они (все) полную точность. Стандарт C ++ явно не упоминает, как рассчитать число пи. Поэтому я склоняюсь к определению числа «пи» вручную. Я хотел бы поделиться решением ниже, которое поддерживает все виды дробей с полной точностью.
источник
В windows (cygwin + g ++) я счел необходимым добавить флаг
-D_XOPEN_SOURCE=500
для препроцессора для обработки определенияM_PI
inmath.h
.источник
M_PI
работы на конкретной платформе. Это уже не комментарий к ответу для какой-либо другой платформы, а ответ для другой платформы - это комментарий к этой.C ++ 14 позволяет вам
static constexpr auto pi = acos(-1);
источник
std::acos
неconstexpr
. Итак, ваш код не будет компилироваться.acos
неconstexpr
в C ++ 14 и не предлагаетсяconstexpr
даже в C ++ 17constexpr
? Очевидно, нет: stackoverflow.com/questions/17347935/constexpr-math-functionsconstexpr
посмотреть, например, ( github.com/kthohr/gcem ). Но они не имеют обратной совместимости с одноименными функциями C, поэтому они не могут перенять старые имена.Некоторые элегантные решения. Я сомневаюсь, что точность тригонометрических функций равна точности типов. Для тех, кто предпочитает писать постоянное значение, это работает для g ++:
Точность 256 десятичных цифр должна быть достаточной для любого будущего типа long long long double. Если требуется больше, посетите https://www.piday.org/million/ .
источник
источник
Ты можешь сделать это:
Если
M_PI
уже определено вcmath
, это не будет делать ничего, кроме включенияcmath
. ЕслиM_PI
он не определен (как, например, в Visual Studio), он определит его. В обоих случаях вы можете использоватьM_PI
чтобы получить значение числа пи.Это значение pi взято из qmath.h Создателя Qt.
источник
Вы можете использовать это:
Математические константы не определены в стандарте C / C ++. Чтобы использовать их, вы должны сначала определить,
_USE_MATH_DEFINES
а затем включитьcmath
илиmath.h
.источник