Der folgende Codeausschnitt alle über das Internet gestreut und scheint mit sehr wenig Änderungen in mehreren verschiedenen Projekten verwendet werden:ULP Vergleichscode
union Float_t {
Float_t(float num = 0.0f) : f(num) {}
// Portable extraction of components.
bool Negative() const { return (i >> 31) != 0; }
int RawMantissa() const { return i & ((1 << 23) - 1); }
int RawExponent() const { return (i >> 23) & 0xFF; }
int i;
float f;
};
inline bool AlmostEqualUlpsAndAbs(float A, float B, float maxDiff, int maxUlpsDiff)
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float absDiff = std::fabs(A - B);
if (absDiff <= maxDiff)
return true;
Float_t uA(A);
Float_t uB(B);
// Different signs means they do not match.
if (uA.Negative() != uB.Negative())
return false;
// Find the difference in ULPs.
return (std::abs(uA.i - uB.i) <= maxUlpsDiff);
}
Siehe zum Beispiel here oder here oder here.
Allerdings verstehe ich nicht, was hier vor sich geht. Zu meinem (vielleicht naiven) Verständnis wird die Gleitkommaelementvariable f
im Konstruktor initialisiert, aber das ganzzahlige Element i
ist nicht.
Ich bin nicht sehr vertraut mit den binären Operatoren, die hier verwendet werden, aber ich kann nicht verstehen, wie Zugriffe von uA.i
und uB.i
produzieren alles andere als Zufallszahlen gegeben, dass keine Zeile im Code tatsächlich die Werte von f
verbindet und i
in irgendeiner sinnvollen Weise.
Wenn mir jemand aufklären könnte warum (und wie) genau dieser Code das gewünschte Ergebnis bringt, würde ich mich sehr freuen!
sieht aus wie einige nicht portable Bittrickerei geht. – NathanOliver
Ich stimme zu. Leider muss ich diesen Code umschreiben und aufräumen, also würde ich gerne verstehen, was genau zuerst passiert :-) – carsten
@carsten, FYI, der Code stammt aus Bruce Dawsons [Blogserie über Fließkomma] (https : //randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). Eine vollständige Erklärung wird dort gegeben. – Pod