643 Stimmen

Verwendung der PI-Konstante in C++

Ich möchte die PI-Konstante und trigonometrische Funktionen in einem C++-Programm verwenden. Ich erhalte die trigonometrischen Funktionen mit include <math.h> . Allerdings scheint es in dieser Header-Datei keine Definition für PI zu geben.

Wie kann ich PI bekommen, ohne es manuell zu definieren?

3 Stimmen

@tiwo, wollen Sie wissen, was der Unterschied ist zwischen 3.14 , 3.141592 et atan(1) * 4 ?

46 Stimmen

Nebenbei bemerkt: cmath sollte in C++ anstelle von math.h verwendet werden, die für C bestimmt ist.

5 Stimmen

In loser Verbindung: siehe cise.ufl.edu/~manuel/obfuscate/pi.c wie man den Wert von PI direkt aus der Definition berechnet.

704voto

Ferenc Deak Punkte 32534

Auf einigen (insbesondere älteren) Plattformen (siehe Kommentare unten) müssen Sie möglicherweise

#define _USE_MATH_DEFINES

und fügen Sie dann die erforderliche Header-Datei ein:

#include <math.h>

und der Wert von pi kann über abgerufen werden:

M_PI

In meinem math.h (2014) ist er definiert als:

# define M_PI           3.14159265358979323846  /* pi */

aber überprüfen Sie Ihre math.h für mehr. Ein Auszug aus der "alten" math.h (im Jahr 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.
 */

Allerdings:

  1. auf neueren Plattformen (zumindest auf meinem 64-Bit-Ubuntu 14.04) muss ich die _USE_MATH_DEFINES

  2. Auf (neueren) Linux-Plattformen gibt es long double Werte auch als GNU-Erweiterung bereitgestellt:

    # define M_PIl          3.141592653589793238462643383279502884L /* pi */

70 Stimmen

#define _USE_MATH_DEFINES gefolgt von #include <math.h> definiert M_PI in Visual C++. Danke.

3 Stimmen

Funktioniert auch mit Cygwin-Headern.

37 Stimmen

Sie können immer einschließen cmath anstelle von math.h .

218voto

C++20 std::numbers::pi

Endlich ist es soweit: http://eel.is/c++Entwurf/Nummern

main.cpp

#include <numbers> // std::numbers
#include <iomanip>
#include <iostream>

int main() {
    std::cout << std::fixed << std::setprecision(20);
    std::cout << "float       " << std::numbers::pi_v<float> << std::endl;
    std::cout << "double      " << std::numbers::pi << std::endl;
    std::cout << "long double " << std::numbers::pi_v<long double> << std::endl;
    std::cout << "exact       " << "3.141592653589793238462643383279502884197169399375105820974944" << std::endl;
}

wobei das genaue Ergebnis mit berechnet wurde:

echo "scale=60; 4*a(1)" | BC_LINE_LENGTH=0 bc -l

gemäß: Wie kann ich pi mit dem Bash-Befehl berechnen?

Kompilieren und ausführen:

g++-10 -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

Sortie :

float       3.14159274101257324219
double      3.14159265358979311600
long double 3.14159265358979323851
exact       3.141592653589793238462643383279502884197169399375105820974944

Getestet auf Ubuntu 20.04 amd64, GCC 10.2.0

Der angenommene Vorschlag beschreibt:

5.0. "Kopfzeilen" [headers] In der Tabelle [tab:cpp.library.headers] wurde eine neue <math> Kopfzeile hinzugefügt werden muss.

[...]

namespace std {
namespace math { 
 template<typename T > inline constexpr T pi_v = unspecified;
   inline constexpr double pi = pi_v<double>;

Außerdem gibt es eine std::numbers::e natürlich :-) Wie berechnet man die Eulersche Konstante oder die Eulersche Kraft in C++?

Diese Konstanten verwenden die C++14-Variablenvorlagenfunktion: C++14 Variable Templates: was ist ihr Zweck? Irgendein Anwendungsbeispiel?

In früheren Fassungen des Entwurfs war die Konstante unter std::math::pi : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0631r7.pdf

1 Stimmen

Ich verstehe nicht, warum das lange Pi mit doppelter Genauigkeit nur zwei Ziffern mehr Genauigkeit hat als das Pi mit doppelter Genauigkeit. Das legt nahe, dass es sich kaum lohnt, long double zu verwenden.

0 Stimmen

@Anachronist gute Beobachtung, ich bin mir nicht ganz sicher, warum dies der Fall ist, lassen Sie es mich wissen, wenn jemand es herausfindet, ich bin jetzt zu faul zum Denken :) Verwandt: stackoverflow.com/questions/15176290/

0 Stimmen

Warum liegt der Float-Wert so weit daneben? 3.xxxxxx74101257324219 ? Es sollte 3,14159265f sein.

196voto

Konamiman Punkte 48557

Pi kann wie folgt berechnet werden atan(1)*4 . Sie könnten den Wert auf diese Weise berechnen und in den Cache stellen.

91 Stimmen

Für C++11-Benutzer: constexpr double pi() { return std::atan(1)*4; }

61 Stimmen

-1: Funktioniert nur, wenn atan(1)*4 == 3.141592653589793238462643383279502884 (grob gesagt). Ich würde nicht darauf wetten. Seien Sie normal und verwenden Sie ein rohes Literal, um die Konstante zu definieren. Warum sollte man an Präzision verlieren, wenn man es nicht muss?

4 Stimmen

@ThomasEding - mein math.h Datei liest #define M_PI 3.14159265358979323846 (falls streng ANSI).

137voto

Henrik Punkte 1117

Holen Sie sie stattdessen von der FPU-Einheit auf dem Chip:

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

double PI = get_PI();

71 Stimmen

:-) wahrscheinlich nicht so plattformunabhängig, aber eine schöne zusätzliche exotische Lösung!

9 Stimmen

Ich finde es toll, wie du hier über den Tellerrand geschaut hast ;)

3 Stimmen

Ich liebe diese Antwort. Es ist besonders nützlich, wenn ältere x86-Plattformen, die eine kleine Modeerscheinung in letzter Zeit ist, wo die Optimierung Compiler sind nicht so schrecklich beteiligt als moderne. Vielen Dank dafür, Henrik!

125voto

BuschnicK Punkte 5134

Sie können auch boost verwenden, das wichtige mathematische Konstanten mit maximaler Genauigkeit für den gewünschten Typ definiert (z. B. float vs. double).

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

Überprüfen Sie die Boost-Dokumentation für weitere Beispiele.

245 Stimmen

Auftrieb: Steigerung der ohnehin schon unnötigen Komplexität von C++ seit 1999!

50 Stimmen

Einprägsam und teilweise wahr. Andererseits kann Boost manchmal phänomenal nützlich sein...

0 Stimmen

Dies wird nicht funktionieren, wenn Sie eine globale Variable PI definieren wollen. Sie werden eine Fehlermeldung erhalten, die besagt 'pi' is not declared in this scope . Ich bin neu in C++, wenn es also eine Möglichkeit gibt, dies zu umgehen, weiß ich es nicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X