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

Hi guys, I'm sure this question has come up before, but I can't make a decent search query that turns up anything useful. Why does it appear that 0 (zero, 0x00) has non-zero bits in it? This came up when I tracked down a bug that ultimately reduced to:
% perl -le 'print vec(0x0, 5,1)' 1
Strange! But:
% perl -le 'print vec(0x0, 6,1)' 0
Huh? And:
% perl -le 'print vec("", 5,1)' 0
I thought "" would be the same as 0 in memory -- all 0 bits! So I naturally looked up the perldoc on vec(), and tried out this:
% perl -le '@bits = split(//, unpack("b*", 0x0)); print "@bits"' 0 0 0 0 1 1 0 0
What gives? Can anyone explain to me why 0 has two non-zero bits in it? And is the only real solution to my bug to just use bit operations rather than vec() (ugh!) Thanks!

Replies are listed 'Best First'.
Re: bits, vec(), zero, and unpack weirdness
by bart (Canon) on May 27, 2004 at 21:36 UTC
    vec works on a string. 0x0 as a string is "0". The ASCII code of this character is 48. There are two nonzero bits in it, bits 4 and 5 (= values 16 and 32 respectively).

    Try testing vec on chr(0) instead.

Re: bits, vec(), zero, and unpack weirdness
by duff (Parson) on May 27, 2004 at 21:35 UTC
    In all cases the zero is in string context and is being treated as such. The bits "0 0 0 0 1 1 0 0" represent the number 48 (the ascii value of 0) To see them in a more familiar order, use "B" instead of "b" :-)
Re: bits, vec(), zero, and unpack weirdness
by Roy Johnson (Monsignor) on May 27, 2004 at 21:37 UTC
    You've got the ASCII representation of the zero character.

    The PerlMonk tr/// Advocate