Bit Shift Left macht Probleme.
MrSpoocy
- perl
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
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
Leider das gleiche Problem.
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
Hi,
Zitat aus der von Georg schon verlinkten Stelle:
Gerhard, nicht Georg, sorry.
MfG ChrisB
Wundert mich halt, weil in C ist es anders, aber laut perl doc wurde das ja genau von C übernommen :/
Hi,
Wundert mich halt, weil in C ist es anders
Unter Verwendung welchen Datentyps ...?
MfG ChrisB
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.
Ich meine natürlich "unsigned char" ;)
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
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
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