in reply to Bit manipulation of a bit stream to generate different elements of an array with each nibble taking either 0 or 1 in perl

I can tell you how to produce all the permutations of 0's and 1's of given bit-width : simply count from 0 to 2^bit_width and print with binary format. But I can not fathom the logic for discarding or accepting some of these. For example, for a width=8 you discarded 1 case. For width=12 you discarded 3 such cases.

#!/usr/bin/perl # author: bliako # date: 16/11/2018 # https://perlmonks.org/?node_id=1225889 # for given width, it counts from 0 to 2**W # and prints the count in binary. # It misses logic to discard some nibbles use strict; use warnings; my $W = 4; # width in nibbles my $count = 0; my $stop = 2**$W; # format an integer as binary my $format = "%0.${W}b"; while( $count < $stop ){ my $x = sprintf($format, $count); # x now contains a binary number of the count # between 0 and the stop 2^width_in_nibbles # now make each digit a nibble, e.g 0 -> 0000 $x =~ s/0/a/g; $x =~ s/1/b/g; $x =~ s/a/0000 /g; $x =~ s/b/1111 /g; print "x=$x ($count)\n"; $count++; }
0 0000 0000 0000 0000 1 0000 0000 0000 1111 2 0000 0000 1111 0000 3 0000 0000 1111 1111 4 0000 1111 0000 0000 5 0000 1111 0000 1111 6 0000 1111 1111 0000 7 0000 1111 1111 1111 8 1111 0000 0000 0000 9 1111 0000 0000 1111 10 1111 0000 1111 0000 11 1111 0000 1111 1111 12 1111 1111 0000 0000 13 1111 1111 0000 1111 14 1111 1111 1111 0000 15 1111 1111 1111 1111
  • Comment on Re: Bit manipulation of a bit stream to generate different elements of an array with each nibble taking either 0 or 1 in perl
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Bit manipulation of a bit stream to generate different elements of an array with each nibble taking either 0 or 1 in perl
by Eily (Monsignor) on Nov 16, 2018 at 10:24 UTC

    You don't need to have the intermediate 'a' and 'b' chars, you could either turn 0s and 1s into the corresponding nibble explicitly:

    $stream =~ s/0/0000 /g; $stream =~ s/1/1111 /g;
    (perl only searches in the part of the string that wasn't already modified, so the 0s in "0000 " aren't turned again).

    Or you could use the power of regexes:

    $stream =~ s/(.)/$1$1$1$1 /g; # could be rewritten using /e and x 4
    Or, if you're fine with hex representation, turn the 1s into F:
    $stream =~ tr/1/F/; print "0x$stream\n";
    0x0000 0x000F 0x00F0 0x00FF 0x0F00 0x0F0F 0x0FF0 0x0FFF 0xF000 0xF00F 0xF0F0 0xF0FF 0xFF00 0xFF0F 0xFFF0 0xFFFF

    ++ for your solution nevertheless :)

      good to know thanks.i like $1$1$1$1.

        I find it kind of hard to read. The /e alternative I mentioned would be something like:

        $stream =~ s/(.)/$1 x 4/eg; # Without extra space $stream =~ s/(.)/($1 x 4).' '/eg; # With extra space
        I didn't include the first one on my post because it felt it would be too many advanced features for a beginner (s/// operator, regex, capture, eval, /g modifier, x operator). But now that I've actually written it down, I find it better than $1$1$1$1: it's actually more intuitive when you read it, and looks less like line noise.

Re^2: Bit manipulation of a bit stream to generate different elements of an array with each nibble taking either 0 or 1 in perl
by BillKSmith (Monsignor) on Nov 16, 2018 at 15:17 UTC
    I think that for each width, he requires only the integers
    [2^($width-1) .. 2^$width-1]
    transformed as others have shown.

    UPDATE: From the viewpoint of 'permutations', discard all permutations that start with '0'.

    Bill
Re^2: Bit manipulation of a bit stream to generate different elements of an array with each nibble taking either 0 or 1 in perl
by spriyada29 (Initiate) on Nov 16, 2018 at 21:12 UTC
    Thanks for the solution. I am actually new to perl and just came up with that weird way to get that output. ;-) But I think the answer is in decimal. After getting these output I added that to an array using the following code  push @strobes,$x; But after that I want to AND(logical) it using a given value. Eg. 00001111--->(offset 3)---> 00001000 11111111--->(offset 2)---> 11111100 I tried to perform any operation on these values but it's treating the values as decimal eg. 00001110-1=1109 Any suggestion on how to perform the logical AND operation.
      use strict; use warnings; # you can declare a nunber in many different formats. # see https://perldoc.perl.org/perlnumber.html # my $N1 = 0b11010111; my $N2 = 0b10110100; # or $N2 = 180; # or $N2 = 0xb4 # logical *bitwise=bit-by-bit* AND: (and not &&), btw OR is | my $N1_AND_N2 = $N1 & $N2; # you can print a number in many different formats # by default it prints in decimal print "Decimal notation: $N1 AND $N2 = $N1_AND_N2\n"; # but youn change the print format using printf (C-like): printf "Binary notation: %b AND %b = %b\n", $N1, $N2, $N1_AND_N2; printf "Hex notation: %x AND %x = %x\n", $N1, $N2, $N1_AND_N2;

      bw, bliako