Je veux utiliser la constante PI et les fonctions trigonométriques dans certains programmes C ++. J'obtiens les fonctions trigonométriques avec include <math.h>
. Cependant, il ne semble pas y avoir de définition de PI dans ce fichier d'en-tête.
Comment puis-je obtenir PI sans le définir manuellement?
c++
trigonometry
Etan
la source
la source
3.14
,3.141592
etatan(1) * 4
?Réponses:
Sur certaines plateformes (en particulier les plus anciennes) (voir les commentaires ci-dessous), vous devrez peut-être
puis inclure le fichier d'en-tête nécessaire:
et la valeur de pi est accessible via:
Dans mon
math.h
(2014), il est défini comme:mais vérifiez votre
math.h
pour plus. Un extrait de "l'ancien"math.h
(en 2009):Toutefois:
sur les plates-formes plus récentes (au moins sur mon Ubuntu 64.04 64 bits), je n'ai pas besoin de définir
_USE_MATH_DEFINES
Sur les plates-formes Linux (récentes), des
long double
valeurs sont également fournies en tant qu'extension GNU:la source
#define _USE_MATH_DEFINES
suivi de#include <math.h>
defineM_PI
en visual c ++. Merci.cmath
au lieu demath.h
._USE_MATH_DEFINES
si GCC se plaint, c'est parce que__STRICT_ANSI__
est défini (peut-être que vous avez réussi-pedantic
ou-std=c++11
) qui interditM_PI
d'être défini, donc indéfinissez-le avec-D__STRICT_ANSI__
. Lorsque vous le définissez vous-même, puisque c'est C ++, au lieu d'une macro, vous devriezconstexpr auto M_PI = 3.14159265358979323846;
.Pi peut être calculé comme
atan(1)*4
. Vous pouvez calculer la valeur de cette façon et la mettre en cache.la source
constexpr double pi() { return std::atan(1)*4; }
atan(1)*4 == 3.141592653589793238462643383279502884
(grosso modo). Je ne parierais pas dessus. Soyez normal et utilisez un littéral brut pour définir la constante. Pourquoi perdre de la précision lorsque vous n'en avez pas besoin?atan2(0, -1);
.atan
ne l'est pasconstexpr
.acos(-1)
plutôt, pas besoinatan2
.Vous pouvez également utiliser boost, qui définit des constantes mathématiques importantes avec une précision maximale pour le type demandé (c'est-à-dire float vs double).
Consultez la documentation de boost pour plus d'exemples.
la source
not gonna use libs
opinion élitiste est un ravageur et probablement la principale raison des mauvais logiciels écrits en C ++.Obtenez-le de l'unité FPU sur puce à la place:
la source
Je recommanderais simplement de taper pi avec la précision dont vous avez besoin. Cela n'ajouterait aucun temps de calcul à votre exécution et serait portable sans utiliser d'en-têtes ou #defines. Le calcul d'acos ou d'atan est toujours plus cher que l'utilisation d'une valeur précalculée.
la source
const
aconstexpr
.constexpr
.Plutôt que d'écrire
Je recommanderais d'utiliser
-D_USE_MATH_DEFINES
ou en/D_USE_MATH_DEFINES
fonction de votre compilateur.De cette façon, vous êtes assuré que même dans le cas où quelqu'un inclurait l'en-tête avant vous (et sans le #define), vous aurez toujours les constantes au lieu d'une erreur de compilation obscure que vous prendrez beaucoup de temps à rechercher.
la source
<cmath>
à différents endroits, cela devient très difficile (en particulier s'il est inclus par une autre bibliothèque que vous incluez). Cela aurait été bien mieux s'ils mettaient cette partie en dehors des protège-têtes, mais ils ne peuvent pas faire grand-chose maintenant. La directive du compilateur fonctionne assez bien en effet.Étant donné que la bibliothèque standard officielle ne définit pas un PI constant, vous devez le définir vous-même. Donc, la réponse à votre question "Comment puis-je obtenir PI sans le définir manuellement?" est "Vous ne le faites pas - ou vous comptez sur certaines extensions spécifiques au compilateur.". Si vous n'êtes pas préoccupé par la portabilité, vous pouvez consulter le manuel de votre compilateur pour cela.
C ++ vous permet d'écrire
mais l'initialisation de cette constante n'est pas garantie d'être statique. Le compilateur G ++ gère cependant ces fonctions mathématiques comme intrinsèques et est capable de calculer cette expression constante au moment de la compilation.
la source
4*atan(1.)
:atan
est facile à mettre en œuvre et la multiplication par 4 est une opération exacte. Bien sûr, les compilateurs modernes plient (visent à plier) toutes les constantes avec la précision requise, et il est parfaitement raisonnable d'utiliseracos(-1)
ou mêmestd::abs(std::arg(std::complex<double>(-1.,0.)))
qui est l'inverse de la formule d'Euler et donc plus esthétique qu'il n'y paraît (j'ai ajoutéabs
parce que je ne ' t rappelez-vous comment le plan complexe est coupé ou s'il est défini du tout).Depuis la page de manuel Posix de math.h :
la source
C ++ 20
std::numbers::pi
Enfin, il est arrivé: http://eel.is/c++draft/numbers
Je m'attends à ce que l'utilisation soit comme:
Je vais essayer quand le support arrivera à GCC, GCC 9.1.0
g++-9 -std=c++2a
ne le supporte toujours pas.La proposition acceptée décrit:
Il y a aussi
std::numbers::e
bien sûr :-) Comment calculer la constante d'Euler ou Euler propulsé en C ++?Ces constantes utilisent la fonction de modèle de variable C ++ 14: Modèles de variable C ++ 14: quel est leur objectif? Un exemple d'utilisation?
Dans les versions précédentes du projet, la constante était sous
std::math::pi
: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdfla source
Le C ++ standard n'a pas de constante pour PI.
De nombreux compilateurs C ++ définissent
M_PI
danscmath
(ou dansmath.h
pour C) une extension non standard. Vous devrez peut-être#define _USE_MATH_DEFINES
avant de pouvoir le voir.la source
je ferais
ou
Je ne taperais pas π avec la précision dont vous avez besoin . Qu'est-ce que cela est même censé signifier? La précision dont vous avez besoin est la précision de
T
, mais nous ne savons rienT
.Vous pourriez dire: de quoi parlez-vous?
T
serafloat
,double
oulong double
. Donc, tapez simplement la précision delong double
, c.-à-d.Mais savez-vous vraiment qu'il n'y aura pas de nouveau type à virgule flottante dans la norme à l'avenir avec une précision encore plus élevée que
long double
? Non.Et c'est pourquoi la première solution est belle. Vous pouvez être sûr que la norme surchargerait les fonctions trigonométriques pour un nouveau type.
Et s'il vous plaît, ne dites pas que l'évaluation d'une fonction trigonométrique à l'initialisation est une pénalité de performance.
la source
arg(log(x)) == π
pour tous0 < x < 1
.J'utilise le suivi dans l'un de mes en-têtes communs dans le projet qui couvre toutes les bases:
En passant, tous les compilateurs ci-dessous définissent les constantes M_PI et M_PIl si vous les incluez
<cmath>
. Il n'est pas nécessaire d'ajouter `#define _USE_MATH_DEFINES qui n'est requis que pour VC ++.la source
M_PI
sans avoir besoin_USE_MATH_DEFINES
Je préfère généralement définir la mienne:
const double PI = 2*acos(0.0);
car toutes les implémentations ne vous la fournissent pas.La question de savoir si cette fonction est appelée au moment de l'exécution ou est statique au moment de la compilation n'est généralement pas un problème, car elle ne se produit qu'une seule fois de toute façon.
la source
double x = pi * 1.5;
, etc.). Si vous avez l'intention d'utiliser PI en mathématiques croquantes dans des boucles serrées, vous feriez mieux de vous assurer que la valeur est connue du compilateur.Je viens de tomber sur cet article de Danny Kalev qui a une excellente astuce pour C ++ 14 et plus.
Je pensais que c'était assez cool (même si j'utiliserais le PI le plus précis possible), surtout parce que les modèles peuvent l'utiliser en fonction du type.
la source
Des valeurs comme M_PI, M_PI_2, M_PI_4, etc. ne sont pas du C ++ standard, donc un constexpr semble une meilleure solution. Différentes expressions const peuvent être formulées qui calculent le même pi et je me demande si elles (toutes) me fournissent la précision totale. Le standard C ++ ne mentionne pas explicitement comment calculer pi. Par conséquent, j'ai tendance à revenir à la définition de pi manuellement. Je voudrais partager la solution ci-dessous qui prend en charge toutes sortes de fractions de pi en toute précision.
la source
Sur Windows (cygwin + g ++), j'ai trouvé nécessaire d'ajouter le drapeau
-D_XOPEN_SOURCE=500
du préprocesseur pour traiter la définition deM_PI
inmath.h
.la source
M_PI
travailler sur une plate-forme particulière. Ce n'est pas un commentaire sur une réponse pour une autre plate-forme, pas plus qu'une réponse pour une autre plate-forme n'est un commentaire sur celle-ci.C ++ 14 vous permet de faire
static constexpr auto pi = acos(-1);
la source
std::acos
n'est pas unconstexpr
. Donc, votre code ne se compilera pas.acos
n'est pasconstexpr
en C ++ 14, et n'est pas proposé de devenirconstexpr
même en C ++ 17constexpr
? Apparemment pas: stackoverflow.com/questions/17347935/constexpr-math-functionsconstexpr
, voir par exemple ( github.com/kthohr/gcem ). Mais ils ne sont pas rétrocompatibles avec les fonctions C du même nom, ils ne peuvent donc pas reprendre les anciens noms.Quelques solutions élégantes. Je doute cependant que la précision des fonctions trigonométriques soit égale à la précision des types. Pour ceux qui préfèrent écrire une valeur constante, cela fonctionne pour g ++: -
La précision de 256 chiffres décimaux devrait suffire pour tout type double long long long long. Si d'autres sont nécessaires, visitez https://www.piday.org/million/ .
la source
la source
Tu peux le faire:
Si
M_PI
est déjà défini danscmath
, cela ne fera rien d'autre que d'inclurecmath
. S'ilM_PI
n'est pas défini (ce qui est le cas par exemple dans Visual Studio), il le définira. Dans les deux cas, vous pouvez utiliserM_PI
pour obtenir la valeur de pi.Cette valeur de pi provient du qmath.h de Qt Creator.
la source
Vous pouvez utiliser cela:
Les constantes mathématiques ne sont pas définies dans le standard C / C ++. Pour les utiliser, vous devez d'abord définir
_USE_MATH_DEFINES
puis inclurecmath
oumath.h
.la source