0 != -0 bei atan2
-
Hallo C++'ler
neulich bin ich über einen Effekt gestolpert, der mir einiges an Arbeit beschert hat. Es geht um den Wert 0.0 beim Typ double. Dieser ist anscheinend nicht zwingend identisch zu -0.0 - wie folgendes kleines Programm zeigt:
#include <cmath> // atan2 #include <iostream> int main() { using namespace std; const double null = 0.0; const double minus_null = -null; if( null != minus_null ) cout << "Mein PC hat in Mathe gepennt " << endl; if( atan2( null, -1.0 ) * atan2( minus_null, -1.0 ) < 0.0 ) cout << "Null ist doch != -Null." << endl; return 0; }Mit VC8 (Windows, Intel) übersetzt und laufen gelassen bekomme ich als Ausgabe:
Null ist doch != -Null.Bitte an Euch (vor allen an die mit abweichender Umgebung) - lasst das Programm mal laufen und berichtet was dann herauskommt.
Gruß
Werner@Edit: -null durch minus_null ausgetauscht - ändert aber nichts
-
Habs unter Code::Blocks laufen lassen und bekam folgendes Ergebnis:
Null ist doch != -Null.
-
Die 0 hat genau eine (eindeutige) Darstellung.
Beweis:
#include <iostream> int main() { double null = 0.0; double _null = -0.0; std::cout << "Ist null == -null? " << std::boolalpha << ( null == _null ) << std::endl; }
-
joar - VS 2005 sagt das auch...
(was daran liegt, dassatan2 (...)einmal pi und einmal -pi rauskommt - wieso das so ist versteh ich allerdings eher nicht ^^)bb
-
Interressant, also ich habe es eben mal selbst getestet und obwohl 0.0 == -0.0 true ist scheinen die beiden verschieden zu sein, denn das Ergebnis von atan2 ist auch bei mir 0 bzw. -0.
Dabei habe ich immer gedacht, dass es bei IEEE Floats nur eine eindeutige Darstellung für die 0 gibt.
-
Hallo,
hier wird wohl beim Auswerten der atan2-Funktion durch den Compiler tatsächlich zwischen -0 und +0 unterschieden. Es gibt auch Varianten von atan2, die +0/-0 berücksichtigen:
http://en.wikipedia.org/wiki/Atan2#Variations
Zwar ein Spezialfall, bei dem beide Argumente Nullen sind, aber wenn es dort schon signifikant für das Ergebnis ist, dann ist es hier offensichtlich auch so.
Beim simplen Vergleich
if( null != minus_null )meint der Compiler, dass eine Unterscheidung nicht nötig ist, obwohl ein Vorzeichenbit auch für die Null mitgeführt wird, wie hier:
http://en.wikipedia.org/wiki/IEEE_floating-point_standard
ersichtlich (nur, um zu zeigen, dass die negative Null im IEEE-Standard mit einbezogen ist).
MfG,
-
Tippgeber schrieb:
Interressant, also ich habe es eben mal selbst getestet und obwohl 0.0 == -0.0 true ist scheinen die beiden verschieden zu sein, denn das Ergebnis von atan2 ist auch bei mir 0 bzw. -0.
Dabei habe ich immer gedacht, dass es bei IEEE Floats nur eine eindeutige Darstellung für die 0 gibt.Ein einfacher Irrtum. Die vorzeichenbehaftete 0 ist nichts Neues, ebenso wenig wie es vorzeichenbehaftete Unendlichkeiten sind. Sie treten allerdings nur im mit transzendenten Funktionen im Zusammenhang mit Grenzwertbetrachtungen auf.
-
camper schrieb:
Die vorzeichenbehaftete 0 ist nichts Neues, ebenso wenig wie es vorzeichenbehaftete Unendlichkeiten sind. Sie treten allerdings nur im mit transzendenten Funktionen im Zusammenhang mit Grenzwertbetrachtungen auf.
.. und bei der Ausgabe - wie ein Hinzufügen der Zeile
cout << null << " != " << minus_null << endl;sofort zeigt.
Und genau das war bei mir das Problem - erzähl mal dem DAU was von Grenzwertbetrachtung und negativer Null
.Also scheint es dann doch Methode zu haben und kein Bug in atan2 ... bin ja mal gespannt, ob sich noch jemand mit einem (Intel outside)MAC meldet.
Gruß
Werner
-
Ich kann noch mit
HP-UX B.11.00 U 9000/800(PA-RISC) und einem Großrechnersystem mit BS2000/OSD6 dienen. Bei ersterem ist die Ausgabe dieselbe wie bei den anderen Kommentatoren. Bei der Großmaschine erhalte ich garkeine Ausgabe.Leider kann ich keine genaueren Angaben zu dem Ding machen, bis auf die Tatsache, dass führende Köpfe in unserem Haus meinen "die Maschine dürfte es seit 20 Jahren nicht mehr geben"

-
Edit: gelöscht...