Warum gibt Splint (der C-Code-Prüfer) beim Vergleich eines Floats mit einem Int einen Fehler aus?

StackOverflow https://stackoverflow.com/questions/38027

  •  09-06-2019
  •  | 
  •  

Frage

Beides sind mathematische Werte, der Gleitkommawert ist jedoch präziser.Ist das der einzige Grund für den Fehler – der Unterschied in der Präzision?Oder gibt es ein anderes potenzielles (und schwerwiegenderes) Problem?

War es hilfreich?

Lösung

Dies liegt daran, dass die Menge der Ganzzahlwerte nicht mit der Menge der Float-Werte für die Typen „int“ und „float“ übereinstimmt.Beispielsweise gibt es für den Gleitkommawert 0,5 kein Gleichheitsmerkmal im Ganzzahlsatz und der Ganzzahlwert 4519245367 ist möglicherweise nicht im Wertesatz vorhanden, den ein Gleitkommawert speichern kann.Daher markiert der Prüfer dies als ein Problem, das vom Programmierer überprüft werden muss.

Andere Tipps

Weil es wahrscheinlich keine sehr gute Idee ist.Nicht alle Floats können auf Ints gekürzt werden.Nicht alle Ints können in Floats konvertiert werden.

Beim Vergleich wird der Ganzzahlwert zu einem Gleitkommawert „heraufgestuft“.An diesem Punkt führen Sie einen exakten Gleichheitsvergleich zwischen zwei Gleitkommazahlen durch, was fast immer eine schlechte Sache ist.

Sie sollten im Allgemeinen eine Art „Epsilon-Kugel“ oder einen Bereich akzeptabler Werte haben und den Vergleich durchführen, wenn die beiden Werte nahe genug beieinander liegen, um als gleich angesehen zu werden.Sie benötigen eine Funktion, die ungefähr so ​​aussieht:

int double_equals(double a, double b, double epsilon)
{
   return ( a > ( b - epsilon ) && a < ( b + epsilon ) );
}

Wenn Ihre Anwendung keine offensichtliche Epsilon-Auswahl hat, verwenden Sie DBL_EPSILON.

Weil Floats keinen exakten int-Wert speichern können. Wenn Sie also zwei Variablen haben, int i und float f, wird der Vergleich „if (i == f)“ wahrscheinlich nicht funktionieren, selbst wenn Sie „i = f;“ zuweisen Rückkehr wahr.

Unter der Annahme von vorzeichenbehafteten Ganzzahlen und dem IEEE-Gleitkommaformat sind die Größen der darstellbaren Ganzzahlen wie folgt:

short  -> 15 bits
float  -> 23 bits
long   -> 31 bits
double -> 52 bits

Deshalb a float kann irgendein darstellen short und ein double kann irgendein darstellen long.

Wenn Sie dies umgehen müssen (Sie haben einen legitimen Grund und sind zufrieden, dass keines der in den anderen Antworten genannten Probleme ein Problem für Sie darstellt), dann wechseln Sie einfach von einem Typ zum anderen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top