MrSpoocy: Bit Shift Left macht Probleme.

Hi,

hier ein kleiner Pseudocode...

my $ts = 77;  
my $right = $ts >> 4;  
my $left = $ts << 4;  
my $result = $right | $left;  
  
print "D: ".sprintf("%08b", $ts)."\n\n";  
print "R: ".sprintf("%08b", $right)."\n";  
print "L: ".sprintf("%08b", $left)."\n";  
print "-" x 11 . "\n";  
print "#: ".sprintf("%08b", $result)."\n\n";

Folgende Ausgabe habe ich erwartet:

/*  
D: 01001101  
  
R: 00000100  
L: 11010000  
-----------  
#: 11010100  
*/

leider habe ich aber folgendes bekommen:

/*  
D: 01001101  
  
R: 00000100  
L: 10011010000  
-----------  
#: 10011010100  
*/

Beim Links shiften füllt er zwar wie gewollt von rechts mit 0 auf, jedoch erweitert er den String einfach. Ich könnte den jetzt sicher mit substr abschneiden, kann mir aber nicht vorstellen das das richtig ist was bei mir pasiert. Weiß jemand was falsch ist und wie ich es behebe ?

mfg Spoocy

  1. Folgendes hab ich hier gefunden: http://www.webbasedprogramming.com/Perl-Quick-Reference/ch3.htm#doubleGthen
    "CAUTION  Bit shift operators depend on the implemention of storage on the machine being used and so may not be portable."

    Versuch mal anstelle in einer Operation 4x zu shiften in 4 Operationen 1x zu shiften. Vielleicht macht das den Unterschied aus.

    lG,
    Gerhard

    1. Leider das gleiche Problem.

  2. Hi,

    Beim Links shiften füllt er zwar wie gewollt von rechts mit 0 auf, jedoch erweitert er den String einfach. Ich könnte den jetzt sicher mit substr abschneiden, kann mir aber nicht vorstellen das das richtig ist was bei mir pasiert. Weiß jemand was falsch ist und wie ich es behebe ?

    Zitat aus der von Georg schon verlinkten Stelle:

    “If you shift by one to the left, you effectively add a new least significant bit with a value of zero (doubling the actual value of the variable).”

    Wenn da einfach irgendwas abegschnitten würde, hättest du nicht dieses definierten Verhalten der Verdoppelung des Wertes.

    Works as designed.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hi,

      Zitat aus der von Georg schon verlinkten Stelle:

      Gerhard, nicht Georg, sorry.

      MfG ChrisB

      --
      RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
      1. Wundert mich halt, weil in C ist es anders, aber laut perl doc wurde das ja genau von C übernommen :/

        1. Hi,

          Wundert mich halt, weil in C ist es anders

          Unter Verwendung welchen Datentyps ...?

          MfG ChrisB

          --
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          1. Hi,

            Wundert mich halt, weil in C ist es anders

            Unter Verwendung welchen Datentyps ...?

            MfG ChrisB

            char, mir ist klar warum in C das so ist, er hat ja nicht mehr Speicher zur Verfügung. Aber in perl kann man ja nicht casten.

            1. Ich meine natürlich "unsigned char" ;)

            2. Hi,

              char, mir ist klar warum in C das so ist, er hat ja nicht mehr Speicher zur Verfügung. Aber in perl kann man ja nicht casten.

              Dann wirst du wohl einen „Umweg“ wie bspw. substr nehmen müssen, wenn du vergleichbares Verhalten in einer in der Hinsicht absolut nicht vergleichbaren Sprache bekommen willst.

              MfG ChrisB

              --
              RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            3. Moin Moin!

              Wundert mich halt, weil in C ist es anders Unter Verwendung welchen Datentyps ...? char,

              Wie kommst Du auf das schmale Brett? Bit Shift ist eine Integer-Operation, die Perl natürlich auf Integern ausführt. Die Breite der Integer hängt an den Optionen, mit denen Perl compiliert wurde, typischerweise sind sie 32 Bit oder 64 Bit breit.

              Zu sehen z.B. mit diesem Stückchen Code:

              
              #!/usr/bin/perl
              use strict;
              use warnings;
              my $x=1;
              for (1..65) {
              	$x<<=1;
              	printf "1 << %2d = %065bb\n",$_,$x;
              }
              
              

              Mit einem 32-Bit-Perl sieht die Ausgabe so aus:

              1 <<  1 = 00000000000000000000000000000000000000000000000000000000000000010b 1 <<  2 = 00000000000000000000000000000000000000000000000000000000000000100b 1 <<  3 = 00000000000000000000000000000000000000000000000000000000000001000b 1 <<  4 = 00000000000000000000000000000000000000000000000000000000000010000b 1 <<  5 = 00000000000000000000000000000000000000000000000000000000000100000b 1 <<  6 = 00000000000000000000000000000000000000000000000000000000001000000b 1 <<  7 = 00000000000000000000000000000000000000000000000000000000010000000b 1 <<  8 = 00000000000000000000000000000000000000000000000000000000100000000b 1 <<  9 = 00000000000000000000000000000000000000000000000000000001000000000b 1 << 10 = 00000000000000000000000000000000000000000000000000000010000000000b 1 << 11 = 00000000000000000000000000000000000000000000000000000100000000000b 1 << 12 = 00000000000000000000000000000000000000000000000000001000000000000b 1 << 13 = 00000000000000000000000000000000000000000000000000010000000000000b 1 << 14 = 00000000000000000000000000000000000000000000000000100000000000000b 1 << 15 = 00000000000000000000000000000000000000000000000001000000000000000b 1 << 16 = 00000000000000000000000000000000000000000000000010000000000000000b 1 << 17 = 00000000000000000000000000000000000000000000000100000000000000000b 1 << 18 = 00000000000000000000000000000000000000000000001000000000000000000b 1 << 19 = 00000000000000000000000000000000000000000000010000000000000000000b 1 << 20 = 00000000000000000000000000000000000000000000100000000000000000000b 1 << 21 = 00000000000000000000000000000000000000000001000000000000000000000b 1 << 22 = 00000000000000000000000000000000000000000010000000000000000000000b 1 << 23 = 00000000000000000000000000000000000000000100000000000000000000000b 1 << 24 = 00000000000000000000000000000000000000001000000000000000000000000b 1 << 25 = 00000000000000000000000000000000000000010000000000000000000000000b 1 << 26 = 00000000000000000000000000000000000000100000000000000000000000000b 1 << 27 = 00000000000000000000000000000000000001000000000000000000000000000b 1 << 28 = 00000000000000000000000000000000000010000000000000000000000000000b 1 << 29 = 00000000000000000000000000000000000100000000000000000000000000000b 1 << 30 = 00000000000000000000000000000000001000000000000000000000000000000b 1 << 31 = 00000000000000000000000000000000010000000000000000000000000000000b 1 << 32 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 33 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 34 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 35 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 36 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 37 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 38 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 39 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 40 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 41 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 42 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 43 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 44 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 45 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 46 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 47 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 48 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 49 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 50 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 51 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 52 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 53 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 54 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 55 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 56 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 57 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 58 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 59 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 60 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 61 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 62 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 63 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 64 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 65 = 00000000000000000000000000000000000000000000000000000000000000000b

              Ein 64-Bit-Perl sollte bis 1<<63 von 0 verschiedene Werte liefern.

              Wenn Du Shift-Operationen auf eine gewisse Anzahl von Bits beschneiden willst, nutze den binären AND-Operator. substr ist an der Stelle einfach nur Verschwendung von Rechenzeit.

              
              #!/usr/bin/perl
              use strict;
              use warnings;
              my $x=1;
              for (1..65) {
              	$x<<=1;
              	$x&=0xFFFF;
              	printf "1 << %2d = %065bb\n",$_,$x;
              }
              
              
              

              Ergebnis:

              1 <<  1 = 00000000000000000000000000000000000000000000000000000000000000010b 1 <<  2 = 00000000000000000000000000000000000000000000000000000000000000100b 1 <<  3 = 00000000000000000000000000000000000000000000000000000000000001000b 1 <<  4 = 00000000000000000000000000000000000000000000000000000000000010000b 1 <<  5 = 00000000000000000000000000000000000000000000000000000000000100000b 1 <<  6 = 00000000000000000000000000000000000000000000000000000000001000000b 1 <<  7 = 00000000000000000000000000000000000000000000000000000000010000000b 1 <<  8 = 00000000000000000000000000000000000000000000000000000000100000000b 1 <<  9 = 00000000000000000000000000000000000000000000000000000001000000000b 1 << 10 = 00000000000000000000000000000000000000000000000000000010000000000b 1 << 11 = 00000000000000000000000000000000000000000000000000000100000000000b 1 << 12 = 00000000000000000000000000000000000000000000000000001000000000000b 1 << 13 = 00000000000000000000000000000000000000000000000000010000000000000b 1 << 14 = 00000000000000000000000000000000000000000000000000100000000000000b 1 << 15 = 00000000000000000000000000000000000000000000000001000000000000000b 1 << 16 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 17 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 18 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 19 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 20 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 21 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 22 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 23 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 24 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 25 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 26 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 27 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 28 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 29 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 30 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 31 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 32 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 33 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 34 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 35 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 36 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 37 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 38 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 39 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 40 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 41 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 42 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 43 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 44 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 45 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 46 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 47 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 48 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 49 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 50 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 51 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 52 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 53 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 54 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 55 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 56 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 57 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 58 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 59 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 60 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 61 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 62 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 63 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 64 = 00000000000000000000000000000000000000000000000000000000000000000b 1 << 65 = 00000000000000000000000000000000000000000000000000000000000000000b

              Alexander

              --
              Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  3. hi,

    Beim Links shiften füllt er zwar wie gewollt von rechts mit 0 auf, jedoch erweitert er den String einfach.

    Ja, das ist so richtig. 4 Bits nach links schieben heißt, die Zahl mit 16 zu multiplizieren. 77 mal 16 => 1232

    1232 binär:  10011010000

    printf "\n%u", 2**10 + 2**7 + 2**6 + 2**4; # 1232

    Beim bitweise OR schreibe gedanklich die Einsnuller rechtsbündig untereinander.

    Hotti