2017-08-30 3 views
2
#include<stdio.h> 

int main() 
{ 

    int loopCounter = 0;  
    float data1,data2; 

    data1 = 2000.0f; 
    data2 = 0.0001f; 

    while(1) 
    {    
     data1 = data1 + data2; 
     printf("Loop Counter %d , Data %f\n",loopCounter,data1); 
     loopCounter++; 
    } 
    return 0; 
} 

ich diesen Code leite auf Linux-Rechner den GCC-Compiler verwenden, aber wenn die Zugabe des 2 Schwimmer 2048.0 den Wert erreicht, es ändert sich nicht mehr.Zwei Gleitkommaaddition ändert sich nicht Ergebnis

Hat jemand eine Idee, warum das passiert?

+5

Was meinst du mit "Halt"? Stoppt es oder druckt es weiterhin den gleichen Wert? – Gerhardh

+1

Kennen Sie die Genauigkeitsbegrenzung von Fließkomma-Datentypen? – Gerhardh

+0

Sie meinen, es "hält", weil es Daten2 hinzufügt, ohne Daten1 zu ändern? Kennen Sie die Ungenauigkeit von Float? Ihr Code ist perfekt, um diesen speziellen Wert zu finden, bei dem die Daten2 so klein sind, dass ihr Affekt nicht in den Akkumulatordaten1 dargestellt werden kann. – Yunnosch

Antwort

4

Für jeden Fließkommawert, in Kombination mit einem (viel) kleineren Addierdelta, gibt es einen Wert, von dem das Hinzufügen des Deltas einen Wert ergibt, der der vorherigen in float ähnlich ist ist identisch.

Ihr Code ist praktisch maßgeschneidert, um diesen Wert zu finden.

Also, während zuerst Delta zu 2000 und einige folgende Werte zu sichtbaren Änderungen führen, wird Ihr Code früher oder später (ziemlich bald tatsächlich) den speziellen Wert erreichen. Was ich bei Ihnen vermute ist 2048.
2048.0 und 2048.0001 haben keine unterschiedliche Darstellung in float. Daher hat das Hinzufügen keine Auswirkung auf die Variable.

+0

Ich habe die Ursache verstanden, aber kann jemand sagen, wie man dies in c-Code vermeiden kann –

+0

Kann gar nicht, Sie können nur breitere Schwimmer verwenden, um das Problem später zu bekommen. – Yunnosch

+0

Sie können jedoch beschreiben, was Sie tatsächlich erreichen möchten, in einer separaten Frage, zeigen Sie, was Sie haben (was mehr/anders sein kann) und fragen Sie nach konkreterer Hilfe. – Yunnosch

2

Jeder hat eine Idee, warum das passiert?

Wegen der Fließkomma-Präzision.

lesen Ranges of floating point datatype in C?

Beachten Sie, dass:

2000.0001 

übersteigt bereits die Grenze ein float speichern kann (~ 7 Stellen für IEEE-754 mit einfacher Genauigkeit).

Was in Ihrem Fall passiert, ist, dass die Genauigkeit begrenzt ist, was zu dem "Anhalten" -Problem führt, das Sie melden. Mit anderen Worten, nach einiger Zeit hat der Zusatz keinen tatsächlichen Effekt (der sich auf den Benutzer auswirkt).

Damit meine ich, dass die neue Summe ist so nah zur vorherige Summe, dass ihr Schwimmer reprecentation das gleiche ist, data1 verursacht den gleichen Wert zu speichern.

In Ihre Maschine, ist dieser Wert 2048 und alle übrigen Ergänzungen durch ein kleines δ beeinflussen nicht die Float-Darstellung von data1.