Wie als vorgeschlagene Lösung für Given three numbers, find the second greatest of them, schrieb ich:Wie können Trap-Repräsentationen vermieden werden, wenn XOR-Bit-Cancellation für signierte Ints ausgeführt wird?
int second_largest(int a, int b, int c) {
int smallest = min(min(a, b), c);
int largest = max(max(a, b), c);
/* Toss all three numbers into a bag, then exclude the
minimum and the maximum */
return a^b^c^smallest^largest;
}
Die Idee ist, dass ^ smallest^largest
die Bits aufhebt, so dass die mittlere Zahl bleibt.
Allerdings wies @chux ein Problem aus:
Ein Problem mit singulären
int
unda^b^c^smallest^largest
ist, dass ein Zwischenergebnis eine Falle Darstellung auf seltene Komplement Plattformen non-2 sein kann. - chux@chux Bitte erläutern? XOR arbeitet nur Stück für Stück, und es ist mir egal, was die Bits darstellen, richtig? - 200_success
XOR kümmert es nicht, aber das Ergebnis kann ein Problem sein: z.B. mit sagen Vorzeichen-Magnitude Ganzzahlen,
-1^1
geht zu-0
was vielleicht ein Trap-Wert - Stoppen des Codes. siehe C11 §6.2.6.2 2. Bit-weise Ops sind besser für unsigned Typen. - chuxWeitere C11 §6.2.6.2 3 spezifiziert implementierungsdefiniertes Verhalten für^mit int auf seltenen Nicht-2's Komplement-Plattformen. Insbesondere "Es ist nicht spezifiziert, ob diese Fälle tatsächlich eine negative Null oder eine normale Null erzeugen", wodurch ein möglichst kleiner Wert erreicht wird, der so funktioniert, wie es gewünscht wird, selbst wenn ein Trap-Wert nicht verwendet wird. Der nächste Abschnitt erklärt, wie dies UB sein kann. Am besten lassen Sie diesen neuen Code auf vorzeichenlose Typen zurück. - chux
Es scheint bedauerlich, dass eine Technik, die logisch und mathematisch klingen sollte, durch eine Technizität entgleisen könnte.
Gibt es eine Möglichkeit, diese XOR-Technik zu retten und sie rechtssicher zu machen, idealerweise mit null Laufzeitaufwand? (Etwas Gewerkschaften beteiligt, vielleicht?)
Beachten Sie, dass dies nicht nur für XOR gilt - das gleiche Argument könnte auf jeden bitweisen Operator angewendet werden. –
Sie benötigen nur drei Vergleiche, um den zweitgrößten von drei zu erhalten. Wie ist das schlimmer als die multiplen Vergleiche in den ersten beiden Zeilen? – 2501
Ich würde drei Vergleiche durchführen und die Ergebnisse in einen Index codieren und dann die Logik als einen 8-Fall-Schalter implementieren. – user3528438