Bitwise operations: Difference between revisions

→‎{{header|Perl6}}: Added perl 6 solution
(Delphi)
(→‎{{header|Perl6}}: Added perl 6 solution)
Line 1,053:
print 'a << b: ', $a << $b, "\n"; # left shift
print 'a >> b: ', $a >> $b, "\n"; # arithmetic right shift
}</lang>
 
=={{header|Perl 6}}==
 
Bitwise operations in Perl 6 are separated into boolean, buffer and interger contexts. Boolean operators coerce their arguments to booleans and return a boolean value.
Buffer bitwise operators coerce to string buffers and return a buffer. Integer bitwise operators coerce their arguments to integers and return an integer value.
 
<lang perl6>sub bool ($a, $b) {
say 'Coerce to Boolean';
say_bool_buff "$a and $b", $a ?& $b;
say_bool_buff "$a or $b", $a ?| $b;
say_bool_buff "$a xor $b", $a ?^ $b;
say_bool_buff "not $a", !$a;
}
 
sub buf ($a, $b) {
say 'Coerce to Buffer';
say_bool_buff "$a and $b", $a ~& $b;
say_bool_buff "$a or $b", $a ~| $b;
say_bool_buff "$a xor $b", $a ~^ $b;
# say_bool_buff "$a bit shift right $b", $a ~> $b; #NYI in Rakudo
# say_bool_buff "$a bit shift left $b", $a ~< $b; #NYI in Rakudo
}
 
sub int ($a, $b) {
say 'Coerce to Int';
say_bit "$a and $b", $a +& $b;
say_bit "$a or $b", $a +| $b;
say_bit "$a xor $b", $a +^ $b;
say_bit "$a signed bit shift right $b", $a +> $b;
# say_bit "$a unsigned bit shift right $b", $a +> $b :unsigned; #NYI in Rakudo
# say_bit "$a rotate right $b", $a +> $b :rotate; #NYI in Rakudo
say_bit "$a bit shift left $b", $a +< $b;
# say_bit "$a rotate shift left $b", $a +< $b :rotate; #NYI in Rakudo
say_bit "twos complement not $a", +^$a;
 
}
 
bool(7,2);
say '-' x 80;
buf(7,2);
say '-' x 80;
int(7,2);
say '-' x 80;
 
 
sub say_bit ($message, $value) {
my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size
printf("%30s: %4d, %032b\n", $message, $value, $value) if $INTSIZE == 32;
printf("%30s: %4d, %064b\n", $message, $value, $value) if $INTSIZE == 64;
}
 
sub say_bool_buff ($message, $value) {
printf("%30s: %4d, %s\n", $message, $value, $value);
}</lang>
 
 
The integer bitwise unsigned shift and rotate operators have not been implemented
yet since Rakudo is still getting big integer support firmed up, and does not yet
parse adverbs in infix operators. Here are some possible implementations that use
native sized integers. (Rakudo on Parrot only!)
 
 
<lang perl6>sub infix:<bsr>( $a, $b, :$rotate, :$unsigned ) {
if $rotate {
my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size
my $c = $b % $INTSIZE;
return pir::lsr__III($a, $c) +| pir::shl__III((2**$c-1) +& $a, $INTSIZE-$c);
}
if $unsigned {
return pir::lsr__III($a, $b);
}
pir::shr__III($a, $b);
}
 
sub infix:<bsl>( $a, $b, :$rotate, :$unsigned ) {
if $rotate {
my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size
my $c = $b % $INTSIZE;
return pir::shl__III($a, $c) +| pir::lsr__III($a, $INTSIZE-$c);
}
pir::shl__III($a, $b);
}
 
bs_int(7,2);
 
sub bs_int ($a, $b) {
say_bit "$a Signed Bit shift right $b", $a bsr $b;
say_bit "$a Unsigned Bit shift right $b", infix:<bsr>($a, $b, :unsigned);
say_bit "$a Rotate right $b", infix:<bsr>($a, $b, :rotate);
say_bit "$a Bit shift left $b", $a bsl $b;
say_bit "$a Rotate left $b", infix:<bsl>($a, $b, :rotate);
}</lang>
 
10,333

edits