2015-05-06 83 views
7

Zum BeispielWie implementieren C und C++ Compiler die Entscheidung der Gleichheit für Float-Nummern?

float a = 1.0; 
float b = 1.2; 

puts(a == b? "equal": "not equal"); 

Hat Compiler mit ihr umgehen bitwisely oder durch andere Methoden?

(Ich weiß, es ist keine gute Wahl, um die Gleichheit von Fließkommazahlen von „==“ zu entscheiden, ich will nur wissen, wie ein Compiler beschäftigt sich mit dieser Situation.)

+1

Was ist der Unterschied zwischen bitweisem und wertmäßigem Wert? Sicherlich sind sie die gleichen für Schwimmer –

+0

@EdHeal in Ordnung, das Problem ist bearbeitet – Wizmann

+5

Alle Gleitkommazahlen sind in ** IEEE-754 Fließkomma-Format ** gespeichert. Sie sind entweder ** 32-Bit ** (Gleitkommazahl einfacher Genauigkeit) oder ** 64-Bit ** (Gleitkommazahl doppelter Genauigkeit). Das bedeutet, dass es für jede Gleitkommazahl eine ganze Zahl gibt, die auf den Bits im Speicher basiert. Der Compiler handhabt es genauso, wie es eine Ganzzahl äquivalenter Größe tut. Siehe: [** Der Floating-Point Guide - Was jeder Programmierer wissen sollte ... **] (http://floating-point-gui.de/) –

Antwort

5

Die allgemeine, vollständige Antwort lautet, dass Fließkommazahlen gemäß der IEEE 754-Spezifikation verglichen werden.

Ihre Frage speziell zu beantworten, die meiste Zeit zwei Gleitkommazahlen verglichen werden bitweise, mit wenigen Ausnahmefällen:

  • Positive und negative Null sind
  • NaN gleich betrachtet ungleich betrachtet alles, auch auf NaN selbst
  • subnormals kann auf Null und andere subnormals in bestimmten Betriebsarten (zB „flush subnormals auf Null“)
  • Anders als diese ex gleich vergleichen ceptions, wird ein regelmäßiger bitweiser Vergleich verwendet
+3

... außer natürlich, wenn das System keinen IEEE Fließkomma verwendet (z. B. einige IBM Mainframes immer noch nicht, nicht viele GPUs, zumindest normalerweise). –

+1

C++ benötigt kein IEEE754 (obwohl [es gibt eine statische Variable, die Sie überprüfen können, ob ieee754 verwendet wird] (http://stackoverflow.com/questions/5777484/how-to-check-if-c-compiler) -uses-ieee-754-Fließkomma-Standard)). –

1

ich Sie gehe davon aus bedeuten, nachdem das Programm kompiliert wurde, wie vergleicht es zwei Floats. Die Art, wie Schwimmer gespeichert werden, ist sehr einzigartig. Es wird nach Vorzeichen, Exponent und Bruch gespeichert, wie aus here ersichtlich ist. Wenn es nicht absolut gleich ist, sieht das Programm daher sogar 1 und 1,000000000001 als unterschiedlich. Um zu überprüfen, ob sie fast gleich sind, können Sie die folgende verwenden:

bool AlmostEqualRelativeOrAbsolute(float A, float B, 
      float maxRelativeError, float maxAbsoluteError) 
{ 
    if (fabs(A - B) < maxAbsoluteError) 
     return true; 
    float relativeError; 
    if (fabs(B) > fabs(A)) 
     relativeError = fabs((A - B)/B); 
    else 
     relativeError = fabs((A - B)/A); 
    if (relativeError <= maxRelativeError) 
     return true; 
    return false; 
} 

Der Code von here erhalten wird, können Sie mehr auf der Website zu lesen.

3

gcc und clang verwenden Sie die UCOMISS x86/x64-Anweisung.

Quelle: tried it mit -O3 und den Montageausgang überprüft.

+5

Allgemeiner erzeugt der Compiler eine architekturspezifische Anweisung zum Vergleichen von Fließkommazahlen, wenn die Architektur über Hardwareunterstützung für sie verfügt, z. B. x86, x86-64 und ARM. Andernfalls gibt sie eine Befehlsfolge aus, die das erforderliche Verhalten implementiert durch den verwendeten Gleitkommastandard, fast immer IEEE-754. –