Entwickler-Ecke

Basistechnologien - Zwei Int16 aus Int32 herausrechnen (Ergebnis falsch)


mannyk - Do 24.05.12 11:15
Titel: Zwei Int16 aus Int32 herausrechnen (Ergebnis falsch)
Hallo Leute,

ich versuche aus einer 32Bit Ganzzahl zwei 16Bit Zahlen herauszurechnen. Leider stimmt das Ergebnis nicht ganz überein.

Untenstehend baue ich die beiden Zahlen (3 und 2) in eine Int32 Zahl.

C#-Quelltext
1:
2:
3:
ushort a = 3;
ushort b = 2;
int number = (0x10000000 | (a << 16)) | b;


Mit folgender Funktion möchte ich die beiden alten Werte wieder herstellen:

C#-Quelltext
1:
2:
ushort aNew = (ushort)(number & 0x0000ffff);
ushort bNew = (ushort)(number & 0xffff0000 >> 16 & aNew);


Leider kommt für beide Werte aNew und bNew 2 heraus.

Was mache ich falsch?
Danke und LG,
mannyk


Ralf Jansen - Do 24.05.12 11:41

Zitat:
int number = (0x10000000 | (a << 16)) | b;


Was hast du dir dabei gedacht das 0x10000000 dazuzupacken? Du willst doch nur a und b kombinieren?

Zitat:
ushort aNew = (ushort)(number & 0x0000ffff);


Das sind die unteren 16bit wo du b hingeschrieben hast. Das aNew zu nennen ist verdreht aber ansonsten ok.

Zitat:
ushort bNew = (ushort)(number & 0xffff0000 >> 16 & aNew);


Wozu wieder aNew hinzufügen wenn du eigentlich bNew willst. aNew hat da nix zu suchen. Dann solltest du noch mal die Operatorreihenfolge überdenken. Shifts werden vor den binär Operatoren ausgeführt.
Also aNew raus. Richtig Klammern. bNew ist eher aNew und wenn die 0x10000000 aus irgendeinem Grund dabei sein muss musst du die Maske (0xffff0000) anpassen ansonsten ist der Wert dann auch in deinem Ergebnis drin und nicht nur a.


mannyk - Do 24.05.12 13:13

Hallo und danke für deine Antwort,

ich habe nun den Shift mit den Klammern gesetzt und die Verwechslung von aNew und bNew entschärft.
Das "0x10000000" ist leider eine Vorgabe, auf die ich keinen Einfluss habe.
Nun meine Frage: Wie muss ich "0xffff0000" bei aNew denn abändern, damit ich die wieder die 3 herausbekomme?
Ich habe einige Kombinationen versucht, aber bekomme stets nicht das Richtige heraus.


C#-Quelltext
1:
2:
3:
4:
5:
ushort a = 3;
ushort b = 2;
int number = (0x10000000 | (a << 16)) | b;
ushort bNew = (ushort)(number & 0x0000ffff);
ushort aNew = (ushort)(number & (0xffff0000 >> 16));


Danke und lg,
mannyk


Th69 - Do 24.05.12 13:27

Hallo mannyk,

deine Klammerung ist immer noch falsch. Verstehst du überhaupt die Bitoperationen? Sonst schau mal in [Artikel] Bitoperationen in C# [http://www.mycsharp.de/wbb2/thread.php?threadid=48671].

Richtig muß der Code so aussehen:

C#-Quelltext
1:
2:
3:
ushort aNew = (ushort)((number & 0xffff0000) >> 16);
// bzw. kürzer einfach
ushort aNew = (ushort)(number >> 16);

Jetzt mußt du noch noch herausfinden, wie du das gesetzte Bit (0x10000000) eliminierst, um den Ursprungswert von a zu erhalten...


Ralf Jansen - Do 24.05.12 13:32

Zitat:
ich habe nun den Shift mit den Klammern gesetzt


War ne 50:50 Chance. Du hast den falschen Operator geklammert :(

Zitat:
Das "0x10000000" ist leider eine Vorgabe,


Das hört sich dann jetzt nach Hausaufgabe an und ich will nicht einfach vorsagen.

Du hast jetzt schon je nachdem ob du Bits weg haben willst oder nicht 0 (0000) oder f (1111) verwendet. Was könnte das Gegenstück zu 1 (0001) sein?


mannyk - Do 24.05.12 16:02

Hm, bin bis jetzt noch nicht draufgekommen...

Und nein, ich verstehe überhaupt nicht, was "...& 0x0000ffff" genau macht. :)
Und meines Erachtens habe ich die meisten Möglichkeiten ausprobiert.

Eine Hausaufgabe ist es aber nicht.


Ralf Jansen - Do 24.05.12 17:37

Zitat:
Und nein, ich verstehe überhaupt nicht, was "...& 0x0000ffff" genau macht. :)
Und meines Erachtens habe ich die meisten Möglichkeiten ausprobiert.


Die Antwort tut weh.
Wenn du die Dinge die Voraussetzung zur Lösung deines Problems sind nicht verstehst dann ist die Lösung zur Lösung deines Problems diese Grundlagen zu schaffen. Aber auf keinen Fall Codekombinatorik. Da kommt nur Code raus den du nachher nicht verstehst. Und Code von dem du nachher nicht erklären kannst warum er funktioniert wird nicht funktionieren sondern nur in deinem kleinen IT Biotop unter deinem Schreibtisch so tun als ob.


Zum Einstieg

Msdn zum & Operator [http://msdn.microsoft.com/de-de/library/sbf85k1c%28v=vs.100%29.aspx]
Wikipedia zu bitweisen Operatoren [http://de.wikipedia.org/wiki/Bitweiser_Operator]


mats74 - Fr 25.05.12 09:58

Ich würde zuerst einmal eine ganz einfache Form der Verwendung von Bit-Operatoren versuchen und das Grundprinzip begreifen.
In deinem Fall mal erst ohne Bitverschiebung:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
ushort a = 3;
            ushort b = 2;
            int number = 0x10000000 | a | b;
            ushort aNew = (ushort)(number & a);
            ushort bNew = (ushort)(number & b);
            MessageBox.Show(Convert.ToString(aNew));
            MessageBox.Show(Convert.ToString(bNew));

Vielleicht hilft ja das zum Einstieg.