Bitweise Weniger als oder Gleich
Scheint es eine Art von Missverständnis, dass dies ist für einen Wettbewerb.
Ich bin versuchen zu arbeiten, durch eine Aufgabe und ich habe fest auf eine Stunde jetzt.
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y)
{
int greater = (x + (~y + 1))>>31 & 1;
return !(greater)|(!(x^y));
}
Ich bin nur in der Lage, um verwenden von bit-Operatoren, wie angewiesen in die Kommentare.
Ich kann nicht herausfinden, wie zu lösen x <= y
;
Mein Gedanke ist, dass ich einstellen kann x als seine zwei-Komplement (~x +1
) und fügen Sie es mit Y
. Wenn es negativ ist, X
größer ist als Y
. Daher, durch die Negation, die ich bekommen kann den gegenteiligen Effekt.
Ähnlich, ich weiß, dass !(x^y)
entspricht x==y
.
Allerdings
dabei !(greater)|(!(x^y))
nicht wieder den korrekten Wert.
Wo bin ich Durcheinander? Ich fühle mich wie ich ' m fehlt ein kleines bisschen Logik.
- Was bedeutet dies ist ein online-Wettbewerb... ich bin stecken, an einer Aufgabe und ich weiß nicht, wo sich zu bewegen von hier aus.
- Wähler zu Schließen: diese Frage ist zu breit? Scheint ziemlich gut definiert zu mir.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn
x > y
, danny - x
oder(y + (~x + 1))
negativ sein wird, daher die hohe bit auf 1, andernfalls ist es 0. Aber wir wollenx <= y
, das ist die negation dieser.Besser noch, löschen Sie den shift-operator und verwenden eine bit-Maske, die auf die hohe bit:
EDIT:
Als Kommentator Zeiger aus, die obige version ist anfällig für arithmetischen überlauf Fehler. Hier ist eine andere version, die sich über die Grenzfälle.
Erläuterung: die Allgemeine Strategie zur Behandlung der Vorzeichen-bit der Eingänge als logisch getrennt von dem rest der bits, die "Wert-bits", und führen Sie die Subtraktion wie im vorherigen Beispiel, sich nur auf die Wert-bits. In diesem Fall brauchen wir nur die Subtraktion, wo die beiden Eingänge sind entweder beide negativ oder beide nicht-negativ. Dies vermeidet die arithmetischen überlauf.
Da die Größe der
int
streng genommen ist unbekannt, zur Laufzeit, verwenden wirstd::numeric_limits<int>::max()
als eine bequeme Maske für den Wert-bits. Die Maske des Vorzeichen-bit ist einfach die bit-Weise negation der Wert-bits.Drehen, um das eigentliche Ausdruck für
<=
wir Faktor der bit-wise Maskesm
des Vorzeichen-bit in jedem der sub-Ausdrücke und schieben Sie den Vorgang auf der Außenseite des Ausdrucks. Der erste Ausdruck des logischen Ausdrucksx & ~y
ist wahr, wennx
negativ ist undy
ist nicht-negativ. Der erste Faktor, der neben Begriff~(x ^ Y)
ist wahr, wenn beide negativ sind oder beide nicht negativ sind. Der zweite Faktor~((y & vm) + ~(x & vm) + 1))
ist wahr, wenny - x
ist nicht-negativ, in anderen Wortenx <= y
, ignorieren das Vorzeichen-bit. Die beiden Begriffe sind oder würde, also mit c++ logische Ausdruck-syntax, die wir haben:Den
!!
äußersten Operatoren konvertieren die erhöhte Vorzeichen-bit auf ein1
. Schließlich, hier ist der Modernen C++ - Vorlagenconstexpr
version:y
ist die Zweierkomplement-maximum (0111...111), undx
ist die Zweierkomplement minimum (1000...000).Diese Funktionen nicht vollständig funktionieren, weil der überlauf, so, wie ich das problem gelöst. Öhm...
Wirklich genossen Yanagar1 Antwort, die ist sehr einfach zu verstehen.
Eigentlich können wir entfernen, die shift-Operatoren und die Verwendung De-Morgan-Gesetze, die zu einer Verringerung der Anzahl der Betreiber von 15 auf 11.
Hier ist meine Umsetzung(verbringen etwa 3 Stunden...)
y - x == y + ~x + 1
a & 1 << 31 & a
ist die Vereinfachung von!(!(a & (1 << 31)) | !a)
Die Logik ist:
Warum nicht einfach
y >= x
direkt? weil überlauf passieren kann. So habe ich zum Anfang zurückkehren, um zu vermeiden, überlauf.