How to Inverse Bit!

I am just curious.

I have a string ($str = "0101001000101001")
How can I invert all the bit in one line of code?

~ fantasy ~
Who is Participating?
kanduraConnect With a Mentor Commented:
ah ok! then use tr:

$str =~ tr/[01]/[10]/;

$rev = join '', reverse split //, $str;

in other words, split into characters, reverse that array, and join them together with an empty string.
fantasy1001Author Commented:
I want to invert every bit like: 1010110111010110 the reverse the bit order.
If implement at your method, it reverse the string which can be done with

$str = reverse $str;

~ fantasy ~
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

You can use 'pack' and 'unpack' to convert between bit vectors and these 0-and-1 strings. Once in the form of a bit vector, you can manipulate them with 'vec' operations (to select a sub-range of the bit vector) and with the logical operators & (AND), | (OR), ^ (XOR), and -- the operation you're talking about here -- ~ (NOT).

Obviously, there's overhead involved in going to and from bit vectors, but if you have a lot of logical operations, they are considerably more efficient.
the [] in the tr are unnecessary
jmcg, ozo, you are both right. The 'pack' way offers a lot more flexibility. The [] are not needed in this tr.

However, I timed this:

use Benchmark qw/timethese cmpthese/;
$s = '0101001000101001';

printf "s:      %-20s$/", $s;
printf "tr s:   %-20s$/", with_tr();
printf "pack s: %-20s$/", with_pack();

$t = timethese(1000000, {
      tr            => \&with_tr,
      tr_nb      => \&with_tr_nb,
      pack      => \&with_pack,

sub with_tr {
      my $r = $s;
      $r =~ tr/[01]/[10]/;

sub with_tr_nb {
      my $r = $s;
      $r =~ tr/01/10/;

sub with_pack {
      return unpack("b*", ~ pack("b*", $s));

and got these results:
s:      0101001000101001    
tr s:   1010110111010110    
pack s: 1010110111010110    
Benchmark: timing 1000000 iterations of pack, tr, tr_nb...
      pack:  5 wallclock secs ( 5.14 usr +  0.00 sys =  5.14 CPU) @ 194666.15/s (n=1000000)
        tr:  1 wallclock secs ( 2.13 usr +  0.00 sys =  2.13 CPU) @ 468823.25/s (n=1000000)
     tr_nb:  2 wallclock secs ( 2.08 usr +  0.00 sys =  2.08 CPU) @ 480076.81/s (n=1000000)
          Rate  pack    tr tr_nb
pack  194666/s    --  -58%  -59%
tr    468823/s  141%    --   -2%
tr_nb 480077/s  147%    2%    --

So at least my proposed version is the quickest :)
Oh, the overhead of pack and unpack is considerable. It's only worthwhile doing the conversion if you have a number of bit operations to accomplish or there is some space-saving reason to use bitvectors. The conversion in one direction alone is probably just as expensive as the entire tr operation, which is borne out by your results.

What's curious is that adding the brackets somehow reduces the time it takes to perform the tr operation. That is a surprising result.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.