In C gibt es eine Garantie, dass zwei Doppelgänger, deren Werte gleich sind (double1 == double2
), identische Bitmuster haben werden?Sind zwei Doubles mit gleichem Wert garantiert dasselbe Bitmuster?
Antwort
Es gibt keine solche Garantie.
Zum Beispiel gibt es in IEEE floating point format das Konzept der negativen 0. Es vergleicht gleich positiv 0, hat aber eine andere Darstellung.
Hier ist ein Beispiel dafür:
#include <stdio.h>
int main()
{
unsigned long long *px, *py;
double x = 0.0, y = -0.0;
px = (unsigned long long *)&x;
py = (unsigned long long *)&y;
printf("sizeof(double)=%zu\n",sizeof(double));
printf("sizeof(unsigned long long)=%zu\n",sizeof(unsigned long long));
printf("x=%f,y=%f,equal=%d\n",x,y,(x==y));
printf("x=%016llx,y=%016llx\n",*px,*py);
return 0;
}
Ausgang:
sizeof(double)=8
sizeof(unsigned long long)=8
x=0.000000,y=-0.000000,equal=1
x=0000000000000000,y=8000000000000000
EDIT:
Hier ist ein überarbeitetes Beispiel, das nicht vom Typ punning angewiesen:
#include <stdio.h>
void print_bytes(char *name, void *p, size_t size)
{
size_t i;
unsigned char *pdata = p;
printf("%s =", name);
for (i=0; i<size; i++) {
printf(" %02x", pdata[i]);
}
printf("\n");
}
int main()
{
double x = 0.0, y = -0.0;
printf("x=%f,y=%f,equal=%d\n",x,y,(x==y));
print_bytes("x", &x, sizeof(x));
print_bytes("y", &y, sizeof(y));
return 0;
}
Ausgabe:
x=0.000000,y=-0.000000,equal=1
x = 00 00 00 00 00 00 00 00
y = 00 00 00 00 00 00 00 80
Sie können hier den Unterschied in der Darstellung zwischen den beiden sehen. Einer hat das Vorzeichen gesetzt, während der andere nicht.
Hinweis: Bei verschiedenen IEEE _decimal_ FP-Formaten gibt es viele redundante Bitmuster mit demselben Wert. Z.B. [Dezimal-64 Gleitkommaformat] (https://en.wikipedia.org/wiki/Decimal64_floating-point_format) – chux
beachten Sie, dass "-0.0" ist nicht garantiert, tatsächlich geben Sie negative Null –
Beachten Sie, dass Sie Wortspiel über Dereferenzierung nicht eingeben sollten , da dies das strikte Aliasing unterbricht.Ab C99 können Sie 'memcpy' oder Unions verwenden. –
Ja, mit Ausnahme von Null. Es gibt nur eine Möglichkeit, einen bestimmten IEEE-Float- oder Double-Wert darzustellen. Wenn es zwei Möglichkeiten gäbe, denselben Wert darzustellen, wäre das verschwenderisch und die IEEE-Formate sind sehr effizient.
Null ist ein Sonderfall, weil es positive und negative Werte von Null gibt und sie werden gleich vergleichen, und sie sind für die meisten Zwecke gleich. Es gibt ein paar seltene Fälle (1/0), bei denen sie unterschiedliche Ergebnisse liefern - positive und negative Unendlichkeit.
Die vorherige Antwort konzentrierte sich unnötigerweise auf den Nullfall und scheiterte, soweit ich das beurteilen konnte, für die anderen 4 Milliarden Floats und 16 Milliarden Milliarden Doppelgänger.
Also sind +0 und -0 die einzigen möglichen Ausnahmen von der Regel? –
Es gibt einige Geometrien, in denen + unendlich und -infinity als gleich betrachtet werden, IEEE-Mathematik behandelt sie jedoch nicht als solche. Es gibt auch NaNs, die zu allem als ungleich betrachtet werden, sogar sich selbst. Also ja, +0 und -0 sind die einzigen Ausnahmen. –
- 1. Sind nicht initialisierte Strukturelemente garantiert ein Wert?
- 2. Was ist ein Bitmuster?
- 3. Sind C-Dotierungen anders als .NET-Doubles?
- 4. Binäre Bitmuster-Kombinationen zählen
- 5. Seltsame zwei Steuerelemente/dasselbe Datenquellenproblem
- 6. Mehrere Enum-Varianten mit gleichem Wert?
- 7. Zwei Klassen in zwei Geräten mit gleichem Klassennamen in Delphi
- 8. Der beste Weg, um 2 Doubles mit gleichem Exponenten zu drucken
- 9. wenn zwei Felder dasselbe ng-Modell haben wie man den Wert des send-Schlüssels schreibt?
- 10. Doubles mit Floats implementieren?
- 11. C# Join zwei int-Listen, wo Werte gleich sind und Werte sind bei gleichem Index
- 12. JTable entfernt Wert aus nebeneinander liegenden Spalten mit gleichem Wert
- 13. Bitmuster (Variablenwert) für Boolean in Java?
- 14. Sind Epochen und Trainingsschritte dasselbe?
- 15. Sind Session und Cookies dasselbe?
- 16. Deklaration von zwei globalen Variablen mit gleichem Namen in C
- 17. Datenbank ignorieren Zeilen mit gleichem Wert in der Spalte - Android
- 18. Wann sind Zeiger auf dasselbe Objekt gleich?
- 19. Sind in Header definierte Funktionen garantiert inline?
- 20. Anruf zwei Funktionen aus gleichem Onclick
- 21. Darstellen mehrerer Datenpunkte mit gleichem Wert in jqPlot
- 22. Sind std :: vector Elemente garantiert zusammenhängend?
- 23. Sind Python-Sortierschlüssel garantiert nur einmal aufgerufen?
- 24. Sind Schwimmer Ungleichheiten garantiert konsistent sein
- 25. Warum sind Shutdown-Skripts nicht garantiert?
- 26. Sind F # Async.Parallel-Ergebnisse garantiert in Ordnung?
- 27. wie Auswahlabfrage in gleichem Wert schreiben
- 28. numpy.isnan (Wert) nicht dasselbe wie Wert == numpy.nan?
- 29. Doubles, das sind * genau * gleich 0 sind für (a == b) Rückkehr
- 30. Sind Upgrades innerhalb derselben Hauptversion garantiert kompatibel mit dem Gerät?
Es ist nicht wirklich eine Frage der Sprache, sondern der PC-Architektur selbst. Wenn Sie daran interessiert sind, können Sie auf numerische Analyse lesen, in jedem Fall nur daran erinnern, dass beim Vergleich floats Sie ihre Differenz gegen einen vernachlässigbaren Wert überprüfen sollten. Dieser Wert sollte für Ihre Anwendung sinnvoll sein, d. H. Obwohl es sinnvoll ist, | a - b | zu vergleichen <0,001 Wenn Sie an der Bedeutung von 1 Bruchzahl interessiert sind, macht es keinen Sinn, wenn Sie Zahlen wie 10^-6 vergleichen, da alles unter 0,001 als gleich betrachtet wird. – mewa
Hinweis: Auch bei gleichem 'doppeltem_ _Wert_: +0.0 und -0.0 ergeben einige Operationen unterschiedliche Ergebnisse: [Welche Operationen und Funktionen auf +0.0 und -0.0 ergeben unterschiedliche arithmetische Ergebnisse?] (Http://stackoverflow.com/q/25332133/2410359) – chux
Ich rieche ein XY-Problem. ** Warum ** willst du dich darauf verlassen? – Olaf