Es ist sehr einfach, positive Doppelte zu vergleichen: Die Normalisierung garantiert uns, dass von Zahlen mit unterschiedlichen Exponenten je größer derjenige ist, dessen Exponent größer ist, und von Zahlen mit demselben Exponenten derjenige größer ist, dessen Mantisse größer ist. Der IEEE 754-Standard hat den Exponenten sorgfältig in die höherwertigen Bits eingefügt, sodass positive Doppelte einfach als int64_t verglichen werden können.
Negative Zahlen sind etwas komplizierter: Sie werden im direkten Code gespeichert , während int64_t im komplementären Code gespeichert wird . Dies bedeutet, dass zur Verwendung eines ganzzahligen Vergleichs die unteren 63 Bits eines Doppels invertiert werden müssen (dies führt zu -0. <+0., Was nicht dem Standard entspricht, aber in der Praxis kein Problem darstellt ). Eine explizite Bitprüfung höherer Ordnung und eine bedingte Verzweigung würden alle Vorteile eines Sprunges zum Ganzzahlvergleich zerstören. aber es gibt einen einfacheren Weg!
inline int64_t to_int64(double x) {
int64_t a = *(int64_t*)&x;
uint64_t mask = (uint64_t)(a >> 63) >> 1;
return a ^ mask;
}
inline bool is_smaller(double x1, double x2) {
return to_int64(x1) < to_int64(x2);
}
a>>63
Füllt alle 64 Bits mit Kopien des Vorzeichenbits und
>>1
löscht dann das höchstwertige Bit.
Daniel Lemires Blog hat etwas anderen Code (mit der gleichen Rechenkomplexität), aber meine Version behält die nützliche Eigenschaft bei
to_int64(0.) == 0