FB18 - Das Forum für Informatik

fb18.de / Bachelorstudieng / PM Technische Informatik

RS - Logische- und Shift-Operationen

RS - Logische- und Shift-Operationen 2011-11-22 00:10
Elrassel
Ich bräuchte einmal Hilfe von einem RS-Erfahrenem Studenten.

Und zwar gibt es auf Aufgabenblatt 4 (wen es interressiert) eine Aufgabe, in der man u.A. die Funktion

int abs(int x)

als straightline-Code in Java realisieren soll. Dies soll ohne Schleifen, ohne If-Else-Abfragen und ohne ternärer Operator geschehen. Und außerdem dürfen nur folgende Operatoren benutzt werden:

! ~ & ^ | + << >> >>>

Als Idee fällt mir nur ein, am Anfang eine Art Fallunterscheidung auf die Art zu machen, dass ich mir das "linkeste" Bit ansehe (wegen Zweierkomplement) und je nach dem weiter zu verfahren:

Falls dieses Bit 0 ist: Fertig
Falls nicht, dann von rechts bis zur ersten 1 beibehalten und danach alles invertieren.

Aber wie mache ich das?

Danke schon einmal im Vorraus!

RE: RS - Logische- und Shift-Operationen 2011-11-22 08:22
Slater
mit 'abs without branching' kannst du in Suchmaschinen was finden, wenn du es nicht selber lösen willst

RE: RS - Logische- und Shift-Operationen 2011-12-02 21:17
konst
z ^ (z >> (sizeof(int) - 1)) + (z >>> (sizeof(int) - 1))
Bei negativen ist das erste bit gesetzt , also wird (z >>> 31) zu 1 und (z >> 31) wird bei negativen voll mit 1 aufgefüllt und dann wird durch xor invertiert, dagegen bei positiven wird (z >> (sizeof(int) - 1)) zu 0 und xor wird nichts invertieren und z >>> 31 ist 0 da bei positiven das Most-Significant-Bit(MSB) 0 ist.

Danke für das interessante Rätsel

RE: RS - Logische- und Shift-Operationen 2011-12-03 09:17
Anonymer User
Es gibt kein sizeof in Java.

RE: RS - Logische- und Shift-Operationen 2011-12-03 13:45
Elrassel
z ^ (z >> (sizeof(int) - 1)) + (z >>> (sizeof(int) - 1))
Bei negativen ist das erste bit gesetzt , also wird (z >>> 31) zu 1 und (z >> 31) wird bei negativen voll mit 1 aufgefüllt und dann wird durch xor invertiert, dagegen bei positiven wird (z >> (sizeof(int) - 1)) zu 0 und xor wird nichts invertieren und z >>> 31 ist 0 da bei positiven das Most-Significant-Bit(MSB) 0 ist.

Danke für das interessante Rätsel

Falls es dich interessiert, gab es da noch eine kürzere Lösung:

int mask = x asr 31; // asr soll hier der arithmetische Rechtsshift sein und 31 wegen der Bitlänge von Integer-1
return (x^mask)+~mask+1;

Es wird wieder eine Maske voller 0-er bzw. 1-er erzeugt und diese dann mit dem Ursprungsbitmuster ge-XOR-t. Dann ist der Term für positive Zahlen bereits richtig, für negative müsste noch 1 hinzuaddiert werden, weswegen wir den XOR-ten Term mit der negierten Maske addieren. Dadurch wird bei dem ursprünglich positivem Bitmuster 1 abgezogen und bei dem ursprünglich negativem nichts. Dann brauch man nur noch 1 hinzuaddieren.

RE: RS - Logische- und Shift-Operationen 2011-12-03 14:39
Anonymer User
Warum so umständlich?

return (x^mask)-mask;

RE: RS - Logische- und Shift-Operationen 2011-12-03 16:23
UncleOwen
Weil das Minuszeichen nicht in der Liste erlaubter Operatoren stand.

RE: RS - Logische- und Shift-Operationen 2011-12-03 17:49
Anonymer User
Aber + ist erlaubt?

return (x + mask) ^ mask;