2016-10-07 3 views
3

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?

+0

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

+0

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

+0

Ich rieche ein XY-Problem. ** Warum ** willst du dich darauf verlassen? – Olaf

Antwort

6

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.

+0

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

+0

beachten Sie, dass "-0.0" ist nicht garantiert, tatsächlich geben Sie negative Null –

+1

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. –

0

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.

+0

Also sind +0 und -0 die einzigen möglichen Ausnahmen von der Regel? –

+0

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. –

Verwandte Themen