Vergleichen der gleichen Float-Werte in C [duplizieren]

7

Wenn ich versuche, 2 gleiche float -Werte zu vergleichen, gibt es im folgenden Code keine "gleichen Werte" aus:

%Vor%

Vielen Dank im Voraus.

    
gursahib.singh.sahni 24.03.2012, 09:41
quelle

7 Antworten

23

Während viele Leute Ihnen sagen werden, Fließkommazahlen immer mit einem Epsilon zu vergleichen (und das ist normalerweise eine gute Idee, obwohl es ein Prozentsatz der Werte sein sollte, die verglichen werden, anstatt eines festen Wertes), ist das hier eigentlich nicht notwendig Sie verwenden Konstanten.

Ihr spezifisches Problem ist hier:

%Vor%

verwendet die doppelte Konstante 0.7 , um eine einzelne Genauigkeitsnummer zu erstellen (wobei einige Genauigkeit verloren geht), während:

%Vor%

vergleicht zwei doppelte Präzisionszahlen ( a wird zuerst befördert).

Die Genauigkeit, die verloren gegangen ist, wenn die doppelte 0.7 in die float a umgewandelt wurde, wird nicht wiedergewonnen, wenn a wieder auf ein Double hochgestuft wird.

Wenn du all diese 0.7 Werte in 0.7f änderst (um float anstatt double zu erzwingen), oder wenn du a einfach zu einem double machst, wird es funktionieren - ich benutze selten float heutzutage, außer ich haben eine riesige Auswahl von ihnen und müssen Platz sparen.

Sie können dies in Aktion sehen mit:

%Vor%

gibt etwas aus (leicht modifiziert, um den Unterschied zu zeigen):

%Vor%     
paxdiablo 24.03.2012, 09:48
quelle
4

Fließkommazahl ist nicht das, was Sie denken, sie sind: Hier sind zwei Quellen mit mehr Informationen: Was jeder Informatiker über Fließkommaarithmetik wissen sollte und Der Fließkomma-Guide .

>

Die kurze Antwort ist, dass aufgrund der Art, wie Gleitkommazahlen dargestellt werden, Sie keinen grundlegenden Vergleich oder Arithmetik durchführen können und erwarten, dass es funktioniert.

    
Simeon Visser 24.03.2012 09:46
quelle
3

Sie vergleichen eine Einzelpräzisionsapproximation von 0,7 mit einer Doppelpräzisionsapproximation. Um die erwartete Ausgabe zu erhalten, sollten Sie verwenden:

%Vor%

Beachten Sie, dass es aufgrund von Repräsentations- und Rundungsfehlern sehr unwahrscheinlich ist, dass bei jedem Vorgang genau 0,7f erhalten werden. Im Allgemeinen sollten Sie prüfen, ob fabs(a-0.7) ausreichend nahe an 0 ist.

Vergessen Sie nicht, dass der genaue Wert von 0.7f nicht wirklich 0.7, sondern etwas niedriger ist:

%Vor%

Der exakte Wert der doppelten Präzisionsdarstellung von 0.7 ist eine bessere Näherung, aber immer noch nicht genau 0.7:

%Vor%     
Joni 24.03.2012 09:49
quelle
2

a ist ein float ; 0.7 ist ein Wert vom Typ double .

Der Vergleich zwischen beiden erfordert eine Konvertierung. Der Compiler konvertiert den float -Wert in einen double -Wert ... und der Wert, der sich aus der Konvertierung von float in double ergibt, ist nicht identisch mit dem Wert, der daraus resultiert, dass der Compiler eine Textfolge konvertiert (der Quellcode) zu einem Doppel.

Vergleichen Sie Gleitkommawerte ( float , double oder long double ) jedoch niemals mit == .

Vielleicht lesen Sie "Was jeder Programmierer über Fließkomma-Arithmetik wissen sollte" .

    
pmg 24.03.2012 09:54
quelle
0

Fließkommazahlen dürfen nicht mit dem Operator "==" verglichen werden.

Anstatt Float-Nummern mit dem Operator "==" zu vergleichen, können Sie eine Funktion wie diese verwenden:

%Vor%     
aleroot 24.03.2012 09:45
quelle
0

Der Mangel an absoluter Genauigkeit in Floats macht es schwieriger, triviale Vergleiche zu machen als für ganze Zahlen. Siehe diese Seite zum Vergleichen von Floats in C. Insbesondere zeigt ein Code-Snippet, das von dort abgehoben wurde, ein 'Workaround' für dieses Problem:

%Vor%

Eine einfache und häufige Problemumgehung besteht darin, ein Epsilon mit Code wie folgt zu versehen:

%Vor%

Dies prüft im Wesentlichen den Unterschied zwischen den Werten innerhalb eines Grenzwerts. Siehe den verlinkten Artikel, warum dies nicht immer optimal ist:)

Ein anderer Artikel ist so ziemlich der De-facto-Standard dessen, was verlinkt ist wenn Leute nach Schwimmern auf SO fragen.

    
Mike Kwan 24.03.2012 09:42
quelle
-1

wenn Sie a mit 0.7 vergleichen müssen als

%Vor%

hier 0,00001 kann zu weniger geändert werden (wie 0,00000001) oder mehr (wie 0,0001) & gt; Es hängt von der Präzision ab, die Sie benötigen.

    
Azad Salam 24.03.2012 09:44
quelle