in reply to I've muddled my bit and byte formats.

First of all, please provide something runnable in your future questions instead of forcing us to do that work.

use strict; use warnings qw( all ); my @binimage = ( "\x00", "\x00", "\x00", "\x00", "\x00", "\x90" ); my $nextrow = 5; my $col = 0; my $subcol = 0; for my $index (0..5) { my $thisrow = $nextrow - $index; print "processing row/column/bit $thisrow/$col/$subcol: " . substr +($binimage[$thisrow], $col, 1) . "\n"; printf ("Incoming byte is %d/%x/%8b/%s. Test bitmask is %d/%x/%8b +/%s.\n", substr($binimage[$thisrow], $col, 1), substr($binimage[$thisrow], $col, 1), substr($binimage[$thisrow], $col, 1), unpack('B8',substr($binimage[$thisrow], $col, 1)), 2**(7-$subcol), 2**(7-$subcol), 2**(7-$subcol), unpack('B8', 2**(7-$subcol))); printf "%s\n", ((substr($binimage[$thisrow], $col, 1)) & 2**(7-$su +bcol))? "1" : "0"; }

Secondly, ALWAYS USE use strict; use warnings qw( all );!!! This is the output of the above program:

printf (...) interpreted as function at a.pl line 13. processing row/column/bit 5/0/0: ▒ Argument "M-^P" isn't numeric in printf at a.pl line 13. Argument "M-^P" isn't numeric in printf at a.pl line 13. Argument "M-^P" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/10010000. Test bitmask is 128/80/100000 +00/00110001. Argument "M-^P" isn't numeric in bitwise and (&) at a.pl line 23. 0 processing row/column/bit 4/0/0: Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/00000000. Test bitmask is 128/80/100000 +00/00110001. Argument "\0" isn't numeric in bitwise and (&) at a.pl line 23. 0 processing row/column/bit 3/0/0: Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/00000000. Test bitmask is 128/80/100000 +00/00110001. Argument "\0" isn't numeric in bitwise and (&) at a.pl line 23. 0 processing row/column/bit 2/0/0: Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/00000000. Test bitmask is 128/80/100000 +00/00110001. Argument "\0" isn't numeric in bitwise and (&) at a.pl line 23. 0 processing row/column/bit 1/0/0: Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/00000000. Test bitmask is 128/80/100000 +00/00110001. Argument "\0" isn't numeric in bitwise and (&) at a.pl line 23. 0 processing row/column/bit 0/0/0: Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Argument "\0" isn't numeric in printf at a.pl line 13. Incoming byte is 0/0/ 0/00000000. Test bitmask is 128/80/100000 +00/00110001. Argument "\0" isn't numeric in bitwise and (&) at a.pl line 23. 0

You are repeatedly using the string resulting from "\x90" as a number, but it's not.

You are repeatedly using the string resulting from "\x00" as a number, but it's not.

Basically, everywhere you have

substr($binimage[$thisrow], $col, 1)
you should have
ord(substr($binimage[$thisrow], $col, 1))

(Inside unpack 'B8' is the exception. That one does expect a string.)

Replies are listed 'Best First'.
Re^2: I've muddled my bit and byte formats.
by murrayn (Sexton) on Oct 09, 2018 at 04:56 UTC

    Thank you!

    The "ord" function was, as you stated, the key to making this work. My immediate need is resolved.

    Clearly there's a subtlety to substr of which I am unaware. $binimage[$thisrow] is just a sequence of storage locations containing bits representing pixels. I, the human being, don't care what they represent; I simply want to know whether the bit I'm looking at contains 1 or 0 and the only way I know how to address that is to grab the byte containing the bit and then try to look inside that.

    You appear to be saying that substr will return the ASCII value represented by the number contained in the selected byte(s) rather than just a sequence of 8 bits I, the computer program, can manipulate how I choose.

      Note that

      "\x01" & 1

      equals 0, not 1. See perldoc perlop "Bitwise String Operators" for why.

        murrayn:   ikegami beat me to it, but some other examples:

        c:\@Work\Perl\monks>perl -wMstrict -le "print qq{\x01} & 1; print qq{\cA} & 1; print qq{\x31} & 1; print '1' & 1; " Argument "^A" isn't numeric in bitwise and (&) at -e line 1. 0 Argument "^A" isn't numeric in bitwise and (&) at -e line 1. 0 1 1


        Give a man a fish:  <%-{-{-{-<

        But "1" & 1 would.

      You appear to be saying that substr will return the ASCII value represented by the number contained in the selected byte(s) rather than just a sequence of 8 bits I, the computer program, can manipulate how I choose.

      substr knows nothing about ASCII. substr returns a portion of the original string

      the only way I know how to address that is to grab the byte containing the bit and then try to look inside that.

      That is what you must do, But you didn't do that. You still had a string.

        I think I sort of realized that I didn't have what I thought I had but I don't understand why that is the case.

        I took a substr one byte long from a variable. Why is that a "string" rather than a byte containing a sequence of 8 bits? What, then, is a "string" in Perl?

        Obviously, I'm missing a subtlety here. I understand that a "string" in C is a sequence of characters terminated with a null but I am not aware of a comparable construct in a typeless Perl.

      In most current programming languages, a "string" is a "string of bytes" or rather "string of characters", not a "string of bits".
      The latter would be explicitly called "bitstring" (or "string of bits", for that matter).