Cosinus-Problem
-
so sorry war ja die ganze zeit gar nich richtig eingeloggt.
problem ist nur das für 91-269 grad negative werte rauskommen müssen,
und bei 90 grad müsste eigentlich exakt 0 rauskommen.
-
schau dir mal std::numeric_limits<T>::epsilon() an
-
In deinem Pi fehlt eine Stelle.
const double PI=3.1415926535897932384626433832795; // ^--- hierAuf den hinteren Rängen hab ich jetzt nicht gekuckt, aber irgendwann passt das eh nicht mehr in einen double.
-
seldon schrieb:
In deinem Pi fehlt eine Stelle.
const double PI=3.1415926535897932384626433832795; // ^--- hierAuf den hinteren Rängen hab ich jetzt nicht gekuckt, aber irgendwann passt das eh nicht mehr in einen double.
Ahh, das erklärt auch, warum es nur auf 10 Stellen genau passt. Das war erstaunlich ungenau.
@Threadersteller: Kann es sein, dass dir nicht klar ist, was -1.5406958e-10 bedeutet?
-
ich denke das es so in etwa -0.0000699 ist, allerdings nicht genau 0
-
warum nicht gleich so?
#include <cmath> const double pi = std::acos(-1.); //ist das eigentlich ISO conform? also eine konstante über ne funktion initialisieren (in c++0x gibts dafür ja constexprWobei darauf zu achten ist, dass -1. double ist. Falls du long double precision willst, musst du 1.L nehmen oder in long double casten, damit die richtige acos funktion benutzt wird.
-
-1.5406958e-10 ist -1.5406958 * 10-10 oder -0.00000000015406958. Mit richtigem Pi kriege ich es auf 6 * 10-17 runter, aber ganz genau wirst du es nie bekommen - Pi ist nicht genau darstellbar, und überhaupt ist die Mantisse eines double begrenzt - in der Regel auf 53 binäre Stellen.
-
alles klar ich hab es jetzt einfach so gemacht:
#include <cstdlib> #include<iostream> #include<math.h> #include<cmath> using namespace std; /* * */ int main(int argc, char** argv) { double a; const double PI=3.1415926535897932384626433832795; double theta = 90*PI/180; a=cos(theta); if(a<0.0001)a=0; cout <<"cos(theta): " <<a <<endl; return 0; }
-
Damit wär ich vorsichtig. Irgendwann machst du mal ne numerische Newton-Iteration und stolperst darüber, dass deine Funktion nicht mehr stetig ist.
Wie wär's mit
std::cout << std::fixed << std::setprecision(4) << std::cos(PI / 2) << std::endl;oder so?
-
Micksen1987 schrieb:
als ergebnis von cos(theta) bekomme ich -1.5406958e-10
Dann ist theta einfach eine schlechte Approximation für pi/2 oder die Implementierung der Cosinus-Funktion ist minderwertig.
Wenn Du mit 64-bit doubles arbeitest sollte bei einem "guten theta" und bei einer "guten Implementierung" bei cos(theta) da etwas rauskommen, was betragsmäißg höchstens 10-15 ist.
Bei IEEE-754 64-bit Fließkommazahlen gibt es 251-1 unterschiedliche Zahlen, die zwischen 1 und 2 liegen und in diesem Fließkommaformat darstellbar sind. pi/2 ist aber nicht dabei. Das heißt, Du kannst pi/2 nur mir theta = pi/2 + error approximieren. Da cos(pi/2 + err) ≈ cos(pi/2) - err und |err| hier bei guter Approximation von pi/2 kleiner als 10-15 sein sollte, müsste auch |cos(pi/2+err)| < 10-15 gelten.
Siehe
- what every computer scientist should know about floating-point arithmetic
- Grundlagen der Numerik (bzgl Fehlerfortpflanzung und co)