20 Stimmen

Kann ich in C eine Gleitkommazahl mit einer Ganzzahl vergleichen und addieren?

Kann ich eine Gleitkommazahl mit einer ganzen Zahl vergleichen?

Wird der Float im Code mit ganzen Zahlen verglichen?

float f;     // f has a saved predetermined floating-point value to it  
if (f >=100){__asm__reset...etc}

Könnte ich auch...

float f;
int x = 100;
x+=f;

Ich muss den Gleitkommawert verwenden f die von einem Lage-Referenzsystem empfangen werden, um einen Positionswert anzupassen x der ein PWM-Signal zur Korrektur der Lage steuert.

22voto

paxdiablo Punkte 809679

Die erste wird gut funktionieren. 100 wird in eine Fließkommazahl umgewandelt, und IEE754 kann alle Ganzzahlen genau als Fließkommazahlen darstellen, bis zu etwa 2 23 .

Die zweite funktioniert auch, wird aber zuerst in eine ganze Zahl umgewandelt, so dass Sie an Präzision verlieren (das ist unvermeidlich, wenn Sie Floats in ganze Zahlen umwandeln).

0 Stimmen

Danke, also das bedeutet, wenn f = 1,0162 wäre es int f == 1, so dass ich nur es, f * = 1000 skalieren müsste; so int f == 1016, um Präzision zu behalten?

0 Stimmen

Man kann nicht alle Ganzzahlen genau als Float darstellen. Nicht mit der 24-Bit-Mantisse von float. Wenn es double wäre, ja, aber nicht float :)

0 Stimmen

@Johannes, Sie haben Recht, ich erinnere mich falsch an eine Frage, die ich vor kurzem beantwortet habe, aktualisiert und korrigiert.

11voto

RBerteig Punkte 39719

Da Sie sich mit den Feinheiten von Fließkommazahlen nicht auskennen, verweise ich Sie auf dieses schöne Papier von David Goldberg: Was jeder Informatiker über Fließkommaarithmetik wissen sollte ( Nachdruck bei Sun).

Nachdem Sie das erschreckt hat, ist die Realität, dass más der Zeit ist Gleitkomma ein großer Segen für die Durchführung von Berechnungen. Und moderne Compiler und Sprachen (einschließlich C) gehen vernünftig mit Konvertierungen um, so dass man sich darüber keine Gedanken machen muss. Es sei denn, Sie tun es.

Die angesprochenen Punkte bezüglich der Genauigkeit sind sicherlich berechtigt. Eine IEEE-Schwebekörper hat effektiv nur eine Genauigkeit von 24 Bit, was weniger ist als eine 32-Bit-Ganzzahl. Verwendung von double für Zwischenberechnungen werden alle Rundungs- und Präzisionsverluste auf die Konvertierung zurück nach float o int .

0 Stimmen

+1 für den WECSSKAFPA-Link, das hat mir das Surfen erspart :)

0 Stimmen

Ich habe die Zeitung überflogen, vielleicht verschiebe ich das auf später... haha

0 Stimmen

Es ist ein bisschen viel Mathematik... aber man kann alle Beweise überfliegen und die wichtigen Punkte verstehen. Der wichtigste Punkt ist einfach, dass es nicht immer einfach ist...

9voto

Michael Carman Punkte 30300

Arithmetik im gemischten Modus (Arithmetik zwischen Operanden unterschiedlichen Typs und/oder unterschiedlicher Größe) ist zulässig, aber anfällig. Der C-Standard definiert Regeln für die Typumwandlung, um die Operanden in eine gemeinsame Darstellung zu konvertieren. Die automatische Typumwandlung ermöglicht es dem Compiler, für Operationen im gemischten Modus etwas Vernünftiges zu tun, aber "vernünftig" bedeutet nicht unbedingt "korrekt".

Um wirklich zu wissen, ob das Verhalten korrekt ist oder nicht, müssen Sie zunächst die Regeln für die Beförderung und dann die Darstellung der Datentypen verstehen. Unter sehr allgemeine Bedingungen:

  • kürzere Typen werden in längere Typen umgewandelt ( float a double , short a int , usw.)
  • Ganzzahlige Typen werden in Fließkomma-Typen umgewandelt
  • signierte/unsignierte Konvertierungen zur Vermeidung von Datenverlusten (unabhängig davon, ob signiert in vorzeichenlos umgewandelt wird oder umgekehrt, hängt von der Größe der jeweiligen Typen ab)

Ob Code wie x > y (wobei x y y verschiedene Arten haben) richtig oder falsch ist, hängt von den Werten ab, die x y y nehmen kann. Meiner Erfahrung nach ist es gängige Praxis, implizite Typkonvertierungen (über den Codierungsstandard) zu verbieten. Der Programmierer muss den Kontext berücksichtigen und alle notwendigen Typkonvertierungen explizit durchführen.

2voto

JaredPar Punkte 699699

Sie können eine Fließkommazahl und eine ganze Zahl vergleichen, sicher. Aber das Problem, das sich dabei stellt, ist die Genauigkeit. In den meisten C/C++-Implementierungen haben float und int die gleiche Größe (4 Byte) und sehr unterschiedliche Genauigkeitsstufen. Keiner der beiden Typen kann alle Werte des anderen Typs aufnehmen. Da ein Typ nicht ohne Präzisionsverlust in den anderen Typ konvertiert werden kann und die Typen nicht nativ verglichen werden können, führt ein Vergleich ohne Berücksichtigung eines anderen Typs in einigen Szenarien zu einem Präzisionsverlust.

Um Präzisionsverluste zu vermeiden, können Sie beide Typen in einen Typ konvertieren, der genügend Präzision hat, um alle Werte von float und int darzustellen. Auf más Systeme, wird Double genau das tun. Das folgende Beispiel führt einen nicht-verlustbehafteten Vergleich durch

float f = getSomeFloat();
int i = getSomeInt();
if ( (double)i == (double)f ) { 
   ...
}

5 Stimmen

Ich denke, Sie wollen ">=" (um der ursprünglichen Frage zu entsprechen) und nicht "==". Die Prüfung auf exakte Gleichheit von Gleitkommazahlen ist fast immer eine schlechte Idee.

1voto

Alphaneo Punkte 11361

LHS definiert die Genauigkeit, Wenn also LHS int und RHS float ist, führt dies zu einem Verlust an Genauigkeit.

Werfen Sie auch einen Blick auf FP-bezogene CFAQ

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X