Quiero usar la constante PI y las funciones trigonométricas en algún programa de C ++. Obtengo las funciones trigonométricas con include <math.h>
. Sin embargo, no parece haber una definición para PI en este archivo de encabezado.
¿Cómo puedo obtener PI sin definirlo manualmente?
c++
trigonometry
Etan
fuente
fuente
3.14
,3.141592
yatan(1) * 4
?Respuestas:
En algunas plataformas (especialmente las más antiguas) (vea los comentarios a continuación) es posible que necesite
y luego incluya el archivo de encabezado necesario:
y se puede acceder al valor de pi a través de:
En mi
math.h
(2014) se define como:pero revisa tu
math.h
para más. Un extracto de lo "viejo"math.h
(en 2009):Sin embargo:
en plataformas más nuevas (al menos en mi Ubuntu 14.04 de 64 bits) no necesito definir el
_USE_MATH_DEFINES
En plataformas Linux (recientes) también hay
long double
valores proporcionados como una extensión GNU:fuente
#define _USE_MATH_DEFINES
seguido de#include <math.h>
defineM_PI
en visual c ++. Gracias.cmath
lugar demath.h
._USE_MATH_DEFINES
si GCC se queja, eso se debe a que__STRICT_ANSI__
está definido (tal vez lo aprobó-pedantic
o-std=c++11
) lo que no seM_PI
puede definir, por lo tanto, no lo defina con-D__STRICT_ANSI__
. Al definirlo usted mismo, ya que es C ++, en lugar de una macro, debería hacerloconstexpr auto M_PI = 3.14159265358979323846;
.Pi se puede calcular como
atan(1)*4
. Puede calcular el valor de esta manera y almacenarlo en caché.fuente
constexpr double pi() { return std::atan(1)*4; }
atan(1)*4 == 3.141592653589793238462643383279502884
(más o menos). No apostaría por eso. Sea normal y use un literal en bruto para definir la constante. ¿Por qué perder precisión cuando no es necesario?atan2(0, -1);
.atan
no lo esconstexpr
.acos(-1)
lugar, no es necesarioatan2
.También puede usar boost, que define constantes matemáticas importantes con la máxima precisión para el tipo solicitado (es decir, float vs double).
Consulte la documentación de impulso para obtener más ejemplos.
fuente
not gonna use libs
es una plaga y probablemente la razón número uno para un mal software escrito en C ++.Obténgalo de la unidad FPU en chip en su lugar:
fuente
Recomendaría simplemente escribir pi con la precisión que necesita. Esto no agregaría tiempo de cálculo a su ejecución, y sería portátil sin usar encabezados o #defines. Calcular acos o atan siempre es más costoso que usar un valor precalculado.
fuente
const
aconstexpr
.constexpr
.En lugar de escribir
Recomendaría usar
-D_USE_MATH_DEFINES
o/D_USE_MATH_DEFINES
dependiendo de su compilador.De esta manera, tiene la seguridad de que incluso en el caso de que alguien incluya el encabezado antes de hacerlo (y sin el #define), seguirá teniendo las constantes en lugar de un oscuro error del compilador que tardará años en rastrear.
fuente
<cmath>
en diferentes lugares, se convierte en un gran dolor (especialmente si está incluido en otra biblioteca que está incluyendo). Hubiera sido mucho mejor si pusieran esa parte fuera de los protectores de cabecera, pero ahora no pueden hacer mucho al respecto. La directiva del compilador funciona bastante bien.Dado que la biblioteca estándar oficial no define un PI constante, tendría que definirlo usted mismo. Entonces, la respuesta a su pregunta "¿Cómo puedo obtener PI sin definirlo manualmente?" es "No lo haces, o confías en algunas extensiones específicas del compilador". Si no le preocupa la portabilidad, puede consultar el manual de su compilador para esto.
C ++ te permite escribir
pero no se garantiza que la inicialización de esta constante sea estática. Sin embargo, el compilador de G ++ maneja esas funciones matemáticas como intrínsecas y puede calcular esta expresión constante en tiempo de compilación.
fuente
4*atan(1.)
:atan
es fácil de implementar y multiplicar por 4 es una operación exacta. Por supuesto, los compiladores modernos doblan (apuntan a doblar) todas las constantes con la precisión requerida, y es perfectamente razonable usarloacos(-1)
o incluso lostd::abs(std::arg(std::complex<double>(-1.,0.)))
que es el inverso de la fórmula de Euler y, por lo tanto, más estéticamente agradable de lo que parece (he agregadoabs
porque no lo hago ' No recuerde cómo se corta el plano complejo o si está definido).Desde la página de manual de Posix de math.h :
fuente
C ++ 20
std::numbers::pi
Por fin, ha llegado: http://eel.is/c++draft/numbers
Espero que el uso sea así:
Lo intentaré cuando llegue el soporte a GCC, GCC 9.1.0 con
g++-9 -std=c++2a
todavía no lo admite.La propuesta aceptada describe:
También hay,
std::numbers::e
por supuesto :-) ¿Cómo calcular la constante de Euler o Euler con C ++?Estas constantes utilizan la función de plantilla variable C ++ 14: Plantillas variables C ++ 14: ¿cuál es su propósito? ¿Algún ejemplo de uso?
En versiones anteriores del borrador, la constante estaba en
std::math::pi
: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdffuente
El estándar C ++ no tiene una constante para PI.
Muchos compiladores de C ++ se definen
M_PI
encmath
(o enmath.h
C) como una extensión no estándar. Puede que tenga que hacerlo#define _USE_MATH_DEFINES
antes de poder verlo.fuente
yo lo haría
o
Yo no escribir en π a la precisión que necesita . ¿Qué se supone que significa eso? La precisión que necesita es la precisión de
T
, pero no sabemos nada al respectoT
.Podrías decir: ¿De qué estás hablando?
T
seráfloat
,double
olong double
. Entonces, solo escriba la precisión delong double
, es decirPero, ¿sabe realmente que no habrá un nuevo tipo de coma flotante en el estándar en el futuro con una precisión aún mayor que
long double
? Usted noY es por eso que la primera solución es hermosa. Puede estar bastante seguro de que el estándar sobrecargaría las funciones trigonométricas para un nuevo tipo.
Y, por favor, no diga que la evaluación de una función trigonométrica en la inicialización es una penalización de rendimiento.
fuente
arg(log(x)) == π
para todos0 < x < 1
.Uso siguiente en uno de mis encabezados comunes en el proyecto que cubre todas las bases:
En una nota al margen, todos los compiladores a continuación definen las constantes M_PI y M_PIl si las incluye
<cmath>
. No es necesario agregar `#define _USE_MATH_DEFINES, que solo es necesario para VC ++.fuente
M_PI
sin necesidad_USE_MATH_DEFINES
Generalmente prefiero definir el mío:
const double PI = 2*acos(0.0);
porque no todas las implementaciones se lo proporcionan.La cuestión de si esta función se llama en tiempo de ejecución o está estática en tiempo de compilación generalmente no es un problema, porque solo ocurre una vez de todos modos.
fuente
double x = pi * 1.5;
y similares). Si alguna vez tiene la intención de utilizar PI en matemáticas crujientes en bucles ajustados, es mejor asegurarse de que el compilador conozca el valor.Acabo de encontrar este artículo de Danny Kalev que tiene un gran consejo para C ++ 14 y versiones posteriores.
Pensé que esto era bastante bueno (aunque usaría el PI de mayor precisión que pudiera), especialmente porque las plantillas pueden usarlo según el tipo.
fuente
Los valores como M_PI, M_PI_2, M_PI_4, etc. no son C ++ estándar, por lo que un constexpr parece una mejor solución. Se pueden formular diferentes expresiones constantes que calculen el mismo pi y me preocupa si (todas) me proporcionan la precisión completa. El estándar C ++ no menciona explícitamente cómo calcular pi. Por lo tanto, tiendo a recurrir a definir pi manualmente. Me gustaría compartir la solución a continuación que admite todo tipo de fracciones de pi con total precisión.
fuente
En windows (cygwin + g ++), he encontrado necesario agregar el indicador
-D_XOPEN_SOURCE=500
para que el preprocesador procese la definición deM_PI
inmath.h
.fuente
M_PI
trabajar en una plataforma en particular. Ese no es un comentario sobre una respuesta para alguna otra plataforma, más que una respuesta para otra plataforma es un comentario sobre esta.C ++ 14 te permite hacer
static constexpr auto pi = acos(-1);
fuente
std::acos
no es unaconstexpr
. Entonces, su código no se compilará.acos
no estáconstexpr
en C ++ 14, y no se propone que seaconstexpr
par en C ++ 17constexpr
? Aparentemente no: stackoverflow.com/questions/17347935/constexpr-math-functionsconstexpr
, por ejemplo ( github.com/kthohr/gcem ). Pero no son compatibles con las funciones C del mismo nombre, por lo que no pueden hacerse cargo de los nombres antiguos.Algunas soluciones elegantes. Sin embargo, dudo que la precisión de las funciones trigonométricas sea igual a la precisión de los tipos. Para aquellos que prefieren escribir un valor constante, esto funciona para g ++: -
La precisión de 256 dígitos decimales debería ser suficiente para cualquier tipo doble futuro largo largo largo. Si se requieren más, visite https://www.piday.org/million/ .
fuente
fuente
Puedes hacerlo:
Si
M_PI
ya está definido encmath
, esto no hará nada más que incluircmath
. SiM_PI
no está definido (como es el caso, por ejemplo, en Visual Studio), lo definirá. En ambos casos, puedes usarM_PI
para obtener el valor de pi.Este valor de pi proviene del qmath.h de Qt Creator.
fuente
Puedes usar eso:
Las constantes matemáticas no están definidas en el estándar C / C ++. Para usarlos, primero debe definir
_USE_MATH_DEFINES
y luego incluircmath
omath.h
.fuente