sin()/cos() liefern falsche Werte



  • Hi
    Ich habe seit kurzem das Problem, dass cos()/sin() bei bestimmten Werten falsche Ergebnisse liefern.
    Hier mal ein paar Beispiele:

    int main()
    {
    	std::wcout << sin(181*D3DX_PI/180) << L"\n"; // -0.0174526
    	std::wcout << sin(D3DX_PI) << L"\n";		 // -8.74228e-008
    	std::wcout << sin(179*D3DX_PI/180) << L"\n"; //  0.0174525
    	std::wcout << sin(90*D3DX_PI/180) << L"\n";  //  1    
    	std::wcout << cos(180*D3DX_PI/180) << L"\n"; // -1 
    	std::wcout << cos(0.0f) << L"\n";			//  1 
    	std::wcout << cos(270*D3DX_PI/180) << L"\n"; //  1.19249e-008
    	std::wcout << cos(90*D3DX_PI/180) << L"\n";  // -4.37114e-008 
    	std::wcout << cos(91*D3DX_PI/180) << L"\n";  // -0.0174525
    }
    

    Wie kommen bei einigen diese komischen Werte zustande? Kann man das irgendwie beheben?



  • Die Funktionen erwarten ihre Parameter im Bogenmaß und geben ihre Ergebnisse auch wieder im Bogenmaß zurück.
    Edit: Guck mal hier -> klick mich



  • Vellas schrieb:

    Die Funktionen erwarten ihre Parameter im Bogenmaß und geben ihre Ergebnisse auch wieder im Bogenmaß zurück.
    Edit: Guck mal hier -> klick mich

    Ich weiß, dass sie bogenmaß haben will, ich füttere sie ja auch mit Bogenmaß. Ich werde es demnächst anders berechnen, nämlich so wie bei deinem link, aber bei std::wcout << sin(D3DX_PI) << L"\n"; dürfte doch wohl gar nix schief laufen.


  • Mod

    noname#4124 schrieb:

    Hi
    Ich habe seit kurzem das Problem, dass cos()/sin() bei bestimmten Werten falsche Ergebnisse liefern.
    Hier mal ein paar Beispiele:

    int main()
    {
    	std::wcout << sin(181*D3DX_PI/180) << L"\n"; // -0.0174526
    	std::wcout << sin(D3DX_PI) << L"\n";		 // -8.74228e-008
    	std::wcout << sin(179*D3DX_PI/180) << L"\n"; //  0.0174525
    	std::wcout << sin(90*D3DX_PI/180) << L"\n";  //  1    
    	std::wcout << cos(180*D3DX_PI/180) << L"\n"; // -1 
    	std::wcout << cos(0.0f) << L"\n";			//  1 
    	std::wcout << cos(270*D3DX_PI/180) << L"\n"; //  1.19249e-008
    	std::wcout << cos(90*D3DX_PI/180) << L"\n";  // -4.37114e-008 
    	std::wcout << cos(91*D3DX_PI/180) << L"\n";  // -0.0174525
    }
    

    Wie kommen bei einigen diese komischen Werte zustande? Kann man das irgendwie beheben?

    ich nehme an, du beziehst dich auf die werte, die sehr nahe bei 0 liegen. das ist aber zu erwarten: auch D3DX_PI kann ja nur eine näherung an π sein - folglich wird auch der funktionswert ebenfalls etwas von 0 abweichen. ein double hat üblicherweise 53 signifikante bits, das sind etwa 5,7 dezimalstellen. das kann bei den trigonometrischen funktionen dann auch als abschätzung der genauigkeit des ergebnisses benutzt werden. die erhaltenen werten an den erwähnten stellen sind alle weitaus kleiner, würde man diese auf 5 oder 6 stellen nach dem komma runden, erhielte man die erwartete 0



  • camper schrieb:

    ich nehme an, du beziehst dich auf die werte, die sehr nahe bei 0 liegen. das ist aber zu erwarten: auch D3DX_PI kann ja nur eine näherung an π sein - folglich wird auch der funktionswert ebenfalls etwas von 0 abweichen. ein double hat üblicherweise 53 signifikante bits, das sind etwa 5,7 dezimalstellen. das kann bei den trigonometrischen funktionen dann auch als abschätzung der genauigkeit des ergebnisses benutzt werden. die erhaltenen werten an den erwähnten stellen sind alle weitaus kleiner, würde man diese auf 5 oder 6 stellen nach dem komma runden, erhielte man die erwartete 0

    D.h. -4.37114e-008 ist gar nicht so weit weg von der 0 wie es aussieht? Sorry, aber ich kan mit dem e-008 überhaupt nichts anfangen.


  • Mod

    4.37114e008=4.37114108=0.0000000437114-4.37114e-008 = -4.37114*10^{-8} = -0.0000000437114



  • Ok. Alle unklarheiten beseitigt. 🙂
    Thx!


Anmelden zum Antworten