2012-04-05 8 views
9

Also ich sehe, dass diese Frage bereits gestellt wurde, aber die Antworten waren ein wenig vage und nicht hilfreich. Okay, ich muss einen c-Ausdruck nur unter Verwendung von "&^~! + | >> < <"Bedingte Anweisung mit bitweisen Operatoren

implementieren Der Ausdruck muss ähneln: a? b: c

Also, von was ich sagen konnte, muss der Ausdruck etwas wie folgt aussehen:

return (a & b) | (~a & c)

Dies funktioniert, wenn a = 0, weil anding es mit b geben Null, und dann wird der oder Ausdruck die rechte Seite zurückgeben, (~a & c) was funktioniert, weil ~ 0 alle Einsen gibt, und Anding c mit allen Einsen gibt c zurück.

Dies funktioniert jedoch nicht, wenn a> 0 ist. Kann jemand versuchen zu erklären, warum dies so ist oder wie man es beheben kann?

Antwort

15

Ich würde a zu einem Boolean mit !!a konvertieren, um 0 oder 1 zu erhalten. x = !!a.

Dann würde ich das in Zweierkomplement negieren. Da Sie kein unäres Minus verfügbar haben, verwenden Sie die Definition der Zweierkomplement-Negation: Invertieren Sie die Bits und fügen Sie dann eins hinzu: y = ~x + 1. Dadurch werden entweder alle Bits gelöscht oder alle Bits gesetzt.

Dann würde ich and, dass direkt mit einer Variablen y & b, seine Inverse mit der anderen: ~y & c. Das ergibt eine 0 für einen der Ausdrücke und die ursprüngliche Variable für den anderen. Wenn wir or diese zusammen haben, wird die Null keine Wirkung haben, also erhalten wir die ursprüngliche Variable unverändert.

+0

Das ist eigentlich perfekt. Also warum fügt das Addieren alles klar oder deutlich? Ich verstehe, warum das passieren muss, aber ich verstehe nicht, wie das passiert. – atb

+0

Wenn wir mit 0 begonnen haben, dann werden alle Einsen umgedreht. Wenn wir eins hinzufügen, werden alle diese auf Nullen zurückgestellt (und der Übertrag wird gesetzt, aber wir ignorieren ihn). Wenn wir mit 1 begannen, ergibt das Spiegeln der Bits 111 ... 10. Das Hinzufügen von 1 dreht die letzte 0 zu einer 1, so dass alle Bits jetzt 1 sind. –

+0

der 'y = ~ x + 1'-Teil hat mich verwirrt; Ich habe schließlich herausgefunden, dass es aufgrund eines Integer-Überlaufs funktioniert, wenn x = 0 ist, aber es ist nicht offensichtlich. 'y = (x << 31) >> 31': Die für mich mehr klare Lösung ersten Schicht war lsb mit Linksverschiebung msb (00000001 => 10000000) und dann mit Rechtsverschiebung Kopie msb –

3

Mit anderen Worten, Sie müssen a alle Bits auf 0 gesetzt haben, wenn ein false (d 0) ist, und haben alle Bits auf 1 gesetzt, wenn a wahr ist (das heißt a > 0).

Für den ersten Fall ist die Arbeit bereits für Sie erledigt; für letzteres - versuchen Sie, das Ergebnis des Ausdrucks ~!1 auszuarbeiten.

+0

Nun, das ist, was ich zuerst dachte. ~! 1 würde alles geben, was perfekt ist. Wenn ich aber ~! A und a = 0 machen würde, dann würde ~! 0 mir 1110 geben, also bin ich mir nicht sicher, was ich von hier aus tun soll: – atb