marinersk has asked for the wisdom of the Perl Monks concerning the following question:

Okay, I am fairly certain I am missing something really, really fundamental here, and my brain just won't lock on to the pattern.

I humbly ask my fellow Monks to find the proper clue × four with which to soundly smack me upside the head:

#/user/bin/perl use strict; my $intval = 66; my $pckval = pack 'c', $intval; my $pckhex = "0x" . (unpack 'H16', "$pckval"); my $stoval = "$pckval" ^ 0x80; my $stohex = "0x" . (unpack 'H16', "$stoval");

Adding old-fashioned brute-force debugging to see what's going on:

print "\$intval = 66; # \$intval = [$intval] - Expecting [66]\n"; print "\$pckval = pack 'c', $intval; # \$pckval = [$pckval] - Expec +ting [B]\n"; print "\$pckhex = \"0x\" . (unpack 'H16', \"$pckval\"); # \$pckhex = +[$pckhex] - Expecting [0x42]\n"; print "\$stoval = \"$pckval\" ^ 0x80; # \$stoval = [$stoval] - Expe +cting [194]\n"; print "\$stohex = \"0x\" . (unpack 'H16', \"$stoval\"); # \$stohex = +[$stohex] - Expecting [0xc2]\n";

This produces results other than what I'm expecting, as shown:

W:\Steve\PerlMonks>perl tpm.pl $intval = 66; # $intval = [66] - Expecting [66] $pckval = pack 'c', 66; # $pckval = [B] - Expecting [B] $pckhex = "0x" . (unpack 'H16', "B"); # $pckhex = [0x42] - Expectin +g [0x42] $stoval = "B" ^ 0x80; # $stoval = [128] - Expecting [194] $stohex = "0x" . (unpack 'H16', "128"); # $stohex = [0x313238] - Ex +pecting [0xc2] W:\Steve\PerlMonks>

My dear fellow Monks, where have I gone astray?

Replies are listed 'Best First'.
Re: Flipping the Sign Bit in pack()'ed Value
by choroba (Cardinal) on Jun 09, 2025 at 12:50 UTC
    You used strict. Very good. But you didn't use warnings. Why?

    When I run the code with warnings, I'm getting

    Argument "B" isn't numeric in numeric bitwise xor (^) at 1.pl line 10.

    But even using

    use feature qw( bitwise );
    and changing the xor line to
    my $stoval = "$pckval" ^. 0x80;
    doesn't fix it according to your expectations:
    $stoval = "B" ^. 0x80; # $stoval = [s28] - Expecting [194] $stohex = "0x" . (unpack 'H16', "s28"); # $stohex = [0x733238] - Ex +pecting [0xc2]

    You need to use a character on the right hand side of the xor, too.

    my $stoval = $pckval ^ "\x80"; # or my $stoval = $pckval ^ chr 0x80; # or my $stoval = $pckval ^ pack 'C', 0x80; # ...

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      choroba wrote:

      You used strict. Very good. But you didn't use warnings. Why?

      Long list of reasons. Short answer: Bad habits, I was in a hurry, and I'm arrogant.

      And that bit me: May the lesson stick well this time

      You need to use a character on the right hand side of the xor, too.

      Thank you. (My instinct was suggesting a typecasting problem; I probably should have followed up on that before posting. Ah, well.)

Re: Flipping the Sign Bit in pack()'ed Value
by NERDVANA (Priest) on Jun 09, 2025 at 14:39 UTC
    Are you sure a "sign bit" is what you have here? IEEE formats have a sign bit, but plain integers are generally 2's complement, so you need to potentially modify every bit to switch between positive and negative. But maybe your example is just omitting those details.

      With two's complement, flipping the "sign" bit will have the effect of subtracting the max negative value (if 1) or adding the max negative value (if 0).

        ikegami wrote:

        With two's complement, flipping the "sign" bit will have the effect of subtracting the max negative value (if 1) or adding the max negative value (if 0).

        Yep. I'm looking for a specific effect and when I expanded the test data to 32-bit integers I saw my error right away.

        It's painfully obvious I haven't done bit-head work in awhile, and it's also painfully obvious that I've been working in PowerShell too much and not enough Perl for far too long.

        I hate to say it, but it's also becoming painfully obvious that my mental faculties are slowing down. Getting old sucks. :-)

        I appreciate the help, though. Thank you.

      NERDVANA wrote:

      Are you sure a "sign bit" is what you have here?

      Yeah, once I got the behavior I was looking for out of the instructions, I then realized I hadn't thought through the problem very well. Already adjusting the algorithm. Just ... y'know, needed the steps to behave (or, more to the point, get my understanding of how the steps would behave in alignment with reality, but, y'know, that's a lotta' words. :-) )

      It's interesting. I'm creating a new standard which is neither Big-Endian nor Little-Endian.

      I think it might need to be dubbed "Bad Endian" when I get it working. :-(
      But it will do what I need and that's of course the final arbiter.

      Thanks for the help and advice. I appreciate it.