John Pietrar
John Pietrar

Reputation: 543

How can I reverse the bits of an unsigned byte in Perl?

For example, the number 178 should convert to the letter "M".

178 is 10110010.

Reversing all of the bits should give 01001101, which is 77 or "M" as a character. I taught about using the Reverse function but I don't know how can I use it on an @array.

use strict;
use warnings 'all';

    open(my $fh1, '<', 'sym.dat') or die $!;
    open(my $fh2, '<', 'sym2.txt') or die $!;
    open my $fh_out, '>', 'symout.txt' or die $!;

    until ( eof $fh1 or eof $fh2 ) {

        my @l1 = map hex, split '', <$fh1>;
        my @l2 = map hex, split '', <$fh2>;
        my $n = @l2 > @l1 ? @l2 : @l1;

        my @sum = map {
            no warnings 'uninitialized';
        $l1[$_] + $l2[$_];
    } 0 .. $n-1;
        @sum = map { split //, sprintf '%08X', $_ } @sum;
        print { $fh_out } "reverse @sum\n";
    }

I am calculating here the sum of hex values but the question is the same I want to reverse the byte values.

Upvotes: 3

Views: 2090

Answers (4)

x-yuri
x-yuri

Reputation: 18893

This might be not the most performant way, but:

sub reverse_bits {
    oct '0b' . join '', reverse split '', sprintf '%08b', shift;
}
printf '0b%08b', reverse_bits oct '0b10110010';  # 0b01001101

Upvotes: 0

ikegami
ikegami

Reputation: 385955

This inverses the bits:

>perl -E"say pack 'C', ~178 & 0xFF"
M

This reverses the bits:

>perl -E"say pack 'B8', unpack 'b8', pack 'C', 178"
M

This reverses the bits:

>perl -E"say pack 'b8', sprintf '%08b', 178"
M

Upvotes: 2

Leon Timmermans
Leon Timmermans

Reputation: 30225

Shortest I can come up with for inverting is ~pack "C", 178 (eta: but your title and your text are quite confusing as to whether you want to flip the bits or reverse them, your bit-pattern has the same result for both but this is not generally the same). In the latter case one could do pack "B8", scalar reverse unpack "B8", pack "C", 178, just don't forget to add a comment to that ;-).

Upvotes: 0

Dave Cross
Dave Cross

Reputation: 69284

You call reverse() on an array, by just passing the array to the function. However, like all Perl functions, you can't put a function call inside a string. So instead of

print { $fh_out } "reverse @sum\n";

You want:

print { $fh_out } reverse(@sum), "\n";

The parentheses around @sum are required here to prevent the newline from being included in the arguments to reverse.

Upvotes: 2

Related Questions