Announcement

Collapse
No announcement yet.

Bit shift und Maskierung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bit shift und Maskierung

    Servus zusammen (nach langer langer zeit mal wieder):

    kann mir jemand auf die sprünge helfen ?

    Folgende Ausgangsituatio hätte ich:


    [highlight=c#]
    private void button6_Click(object sender, EventArgs e)
    {

    int basis1 = 8 ; // mit 4 Bits maximal / max = 15
    int basis2 = 212 ; // mit z.B. 8 Bits maximal
    int bitsBasis1 = 4;

    int b1Undb2 = ((basis2 << bitsBasis1) + basis1); ; // = 3400
    Console.WriteLine("ZusammenSet: aus {0} und {1}: = {2}", basis1, basis2, b1Undb2);

    // die umkehrung wäre !

    int getBasis2 = b1Undb2 >> bitsBasis1; // = 212 - passt !


    // hier mein "ausmaskieren" der oberen bits welches probleme macht !

    int getBasis1 = (b1Undb2 << (32 - bitsBasis1)) >> (32 - bitsBasis1);

    Console.WriteLine("ZusammenGet: aus {0} und {1}: = {2}", getBasis1, getBasis2, b1Undb2);



    }

    [/highlight]

    kann ich die Bits ab Position (hier) 5 nicht einfach wegShiften ?

    bzw. wahrscheinlich gibts da eine LOGISCHERE lösung !? :-)

    vielen dank für eure hilfe
    r.b.
    Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
    Um heute vorm PC zu sitzen!

  • #2
    Ein Rechtshift wird als oberstes Bit das SignBit reinschieben und nicht einfach 0. Dein Rechtsshift fühlt also in diesem Fall den Int mit Einsen auf.
    Ist das irgendwie ein Spiel auf binäres And und Or zu verzichten und es schwer zu machen?

    Comment


    • #3
      ja (für mich ist es schwer zu machen ) - allerdings SPIEL ist mir dann etwas zu abwertend ...

      int b1Undb2 = ((basis2 << bitsBasis1) + basis1); ; // = 3400
      ist klar mit OR
      int b1Undb2 = ((basis2 << bitsBasis1) | basis1); ; // = 3400

      ich kapiers allerdings echt nicht dann wieder die ersten 4 bit rauszulesen
      -
      besser gefragt:

      WIE kann ich die BITS (ab Bitposition 4 in diesem beispiel) denn AUSMASKIEREN ?

      Muss ich statt int uint verwenden ? (da hatte ich irgenwie probleme beim shiften)

      oder vorher "einfach" eine Bitmaske setzen ?
      Zuletzt editiert von Fremder; 26.05.2014, 21:55.
      Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
      Um heute vorm PC zu sitzen!

      Comment


      • #4
        ja (für mich ist es schwer zu machen ) - allerdings SPIEL ist mir dann etwas zu abwertend ...
        Es war nicht abwertend gemeint sondern es sah für mich so als als wolltest du aus irgendeinem Grund nur shifts verwenden.

        Um die untersten 4 bits zu bekommen musst du mit einer Maske verunden die nur die unteren 4 bits enthält.
        Also
        [HIGHLIGHT=C#]int getBasis1 = b1Undb2 & 0xf;[/HIGHLIGHT]

        mit Berechnen der Maske aus bitsBasis1;

        [HIGHLIGHT=C#]int getBasis1 = b1Undb2 & (1 << bitsBasis1) - 1;[/HIGHLIGHT]

        Comment


        • #5
          wuaaaaa *g*

          voll krass, klar "man" sollte ja erstmal die materie KORREKT verstehen (was ich bis zu nem gewissen punkt schon drauf hab).

          ich habe echt auf "doof" und gut glück X-Versuche gestartet und bin nicht auf den grünen zweig geraten .

          Lange Rede - kurzer Sinn: V I E L E N D A N K !!!

          PS: darf ich noch erfahren ob es irgendwelche performance-Vorteile gibt,
          z.B. 0xf -> statt 15 Dezimal (bin: 1111) einzugeben ?

          ... und macht doch wohl auch sinn bei häufiger verwendung gleich
          Constante eins (1 << 1) , zwei (1 << 2) etc. festzulegen ?
          ich habe mal nen array gefüllt und festgestellt, dass
          da nicht wirklich was rauszuholen ist !
          Zuletzt editiert von Fremder; 26.05.2014, 22:40.
          Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
          Um heute vorm PC zu sitzen!

          Comment


          • #6
            PS: darf ich noch erfahren ob es irgendwelche performance-Vorteile gibt,
            z.B. 0xf -> statt 15 Dezimal (bin: 1111) einzugeben ?
            Nein die unterschiedliche Darstellung des gleichen Literals machen keinen Unterschied. Entscheide dich anhand der Lesbarkeit.

            ... und macht doch wohl auch sinn bei häufiger verwendung gleich
            Constante eins (1 << 1) , zwei (1 << 2) etc. festzulegen ?
            Bestimmt. Aber es kommt natürlich genau darauf an was du vergleichst. Ich hab mir mal den generierten IL Code angesehen und da war 0xf bereits ausgerechnet. Der Compiler scheint schlau genug zu sein um im Testcode zu bemerken das sich bitsBasis1 nie ändert und der Teil "(1 << bitsBasis1) - 1" eine Konstante darstellt. Schneller kann man dann natürlich nicht mehr sein.

            Comment


            • #7
              ... Ich hab mir mal den generierten IL Code angesehen und da war 0xf bereits ausgerechnet.

              wo kann ich da nachschauen ?
              VS 12
              danke nochmal
              Vor 4,5 Millionen Jahren lernten ~wir~ aufrecht zu gehen!
              Um heute vorm PC zu sitzen!

              Comment


              • #8
                In Visual Studio beim Debuggen einfach mal das Context Menü im gerade laufenden Code öffnen. Da sollte es eine 'Go to Disassembly' Methode geben.
                Aber eigentlich benutze ich üblicherweise einen der gängigen .Net Decompiler. Aka .Net Reflector, ILSpy, dotPeek etc.

                Comment

                Working...
                X