From: Andy McKenzie on
Hey everyone,

I'm really not sure what's going on here: basically, the bitwise
NOT operator seems to simply not work. Here's an example of what I
see.

============Script============

$ cat bintest2.php

<?php

$bin = 2;
$notbin = ~$bin;

echo "Bin: " . decbin($bin) . " !bin: " . decbin($notbin) . "\n";
echo "Bin: $bin !bin: $notbin\n";


?>
=============================


============Output============

$ php bintest2.php
Bin: 10 !bin: 11111111111111111111111111111101
Bin: 2 !bin: -3

=============================


Obviously that's not the expected response. I expect to get something
more like this:

Bin: 10 !bin: 01
Bin: 2 !bin: 1


Can anyone shed some light on this for me? The server is running an
old version of OpenSUSE, and php --version returns:

PHP 5.2.5 with Suhosin-Patch 0.9.6.2 (cli) (built: Dec 12 2007 03:51:56)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies


I get the same response on an Ubuntu 8.04 LTS server with PHP
5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2.

Thanks in advance,

Alex McKenzie
amckenzie4(a)gmail.com
From: Colin Guthrie on
'Twas brillig, and Andy McKenzie at 20/08/10 16:10 did gyre and gimble:
> Hey everyone,
>
> I'm really not sure what's going on here: basically, the bitwise
> NOT operator seems to simply not work. Here's an example of what I
> see.
>
> ============Script============
>
> $ cat bintest2.php
>
> <?php
>
> $bin = 2;
> $notbin = ~$bin;
>
> echo "Bin: " . decbin($bin) . " !bin: " . decbin($notbin) . "\n";
> echo "Bin: $bin !bin: $notbin\n";
>
>
> ?>
> =============================
>
>
> ============Output============
>
> $ php bintest2.php
> Bin: 10 !bin: 11111111111111111111111111111101
> Bin: 2 !bin: -3
>
> =============================
>
>
> Obviously that's not the expected response. I expect to get something
> more like this:
>
> Bin: 10 !bin: 01
> Bin: 2 !bin: 1
>
>
> Can anyone shed some light on this for me?


The output looks correct to me, so I think it's your expectations that
are incorrect.

You are assuming that you are working with a 2-bit number the in actual
fact you are working with a 32-bit number.

If you did

$bin = 2;
$notbin = ~$bin & 3;

Then this should get the results you want. The bitwise & 3 bit
essentially limits things to a 2-bit number. (3 in binary is represented
by 1's for the two LSBs and 0's for all other bits).

FWIW, the fact that ~2 == -3 is due to twos compliment binary notation:
http://en.wikipedia.org/wiki/Twos_Compliment

Col

--

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
Mandriva Linux Contributor [http://www.mandriva.com/]
PulseAudio Hacker [http://www.pulseaudio.org/]
Trac Hacker [http://trac.edgewall.org/]

From: Peter Lind on
On 20 August 2010 17:10, Andy McKenzie <amckenzie4(a)gmail.com> wrote:
> Hey everyone,
>
>  I'm really not sure what's going on here:  basically, the bitwise
> NOT operator seems to simply not work.  Here's an example of what I
> see.
>
> ============Script============
>
> $ cat bintest2.php
>
> <?php
>
> $bin = 2;
> $notbin = ~$bin;
>
> echo "Bin: " . decbin($bin) . "  !bin:  " . decbin($notbin) . "\n";
> echo "Bin: $bin  !bin:  $notbin\n";
>
>
> ?>
> =============================
>
>
> ============Output============
>
> $ php bintest2.php
> Bin: 10  !bin:  11111111111111111111111111111101
> Bin: 2  !bin:  -3
>
> =============================
>
>
> Obviously that's not the expected response.  I expect to get something
> more like this:
>
> Bin: 10  !bin:  01
> Bin: 2  !bin:  1
>
>
> Can anyone shed some light on this for me?  The server is running an
> old version of OpenSUSE, and php --version returns:
>

You probably need to read up on computer architechture and CS theory -
the ~ operator works fine, your understanding does not. What you're
looking at is the following:

$bin = 2 = 00000000000000000000000000000010 (64 bit number)
~$bin = ~2 = -3 = 11111111111111111111111111111101 (the inverse of the above)

Computers generally do not operate on a couple of bits from a byte -
they tend to operate on a byte, a word, a doubleword, etc (before any
nitpickers interrupt: sure, they can, but most operations don't).
Hence, you're not doing a not operation on just "10", you're doing it
on "00000000000000000000000000000010". And as you are operating on a
signed int, you'll get a negative number out of the ~ operation
(seeing as you flipped the most significant bit).

Regards
Peter

--
<hype>
WWW: http://plphp.dk / http://plind.dk
LinkedIn: http://www.linkedin.com/in/plind
BeWelcome/Couchsurfing: Fake51
Twitter: http://twitter.com/kafe15
</hype>
From: Peter Lind on
On 20 August 2010 17:41, Peter Lind <peter.e.lind(a)gmail.com> wrote:
> On 20 August 2010 17:10, Andy McKenzie <amckenzie4(a)gmail.com> wrote:
>> Hey everyone,
>>
>>  I'm really not sure what's going on here:  basically, the bitwise
>> NOT operator seems to simply not work.  Here's an example of what I
>> see.
>>
>> ============Script============
>>
>> $ cat bintest2.php
>>
>> <?php
>>
>> $bin = 2;
>> $notbin = ~$bin;
>>
>> echo "Bin: " . decbin($bin) . "  !bin:  " . decbin($notbin) . "\n";
>> echo "Bin: $bin  !bin:  $notbin\n";
>>
>>
>> ?>
>> =============================
>>
>>
>> ============Output============
>>
>> $ php bintest2.php
>> Bin: 10  !bin:  11111111111111111111111111111101
>> Bin: 2  !bin:  -3
>>
>> =============================
>>
>>
>> Obviously that's not the expected response.  I expect to get something
>> more like this:
>>
>> Bin: 10  !bin:  01
>> Bin: 2  !bin:  1
>>
>>
>> Can anyone shed some light on this for me?  The server is running an
>> old version of OpenSUSE, and php --version returns:
>>
>
> You probably need to read up on computer architechture and CS theory -
> the ~ operator works fine, your understanding does not. What you're
> looking at is the following:
>
> $bin = 2 = 00000000000000000000000000000010 (64 bit number)

32-bit number, as Colin pointed out.

Peter

--
<hype>
WWW: http://plphp.dk / http://plind.dk
LinkedIn: http://www.linkedin.com/in/plind
BeWelcome/Couchsurfing: Fake51
Twitter: http://twitter.com/kafe15
</hype>
From: Andy McKenzie on
Thanks to everyone who responded. I've dealt with binary math
before, but it never occurred to me (and doesn't seem to be anywhere
in the document page at php.net!) that it would automatically pad the
number I entered.

The example I gave was essentially a test I was running: in the
real script, I'm trying to calculate the number of IP addresses in a
given subnet, and I was getting some seriously weird results. I'm
still not entirely sure what's going on, but this should help.

Thanks again!
-Alex


On Fri, Aug 20, 2010 at 11:42 AM, Peter Lind <peter.e.lind(a)gmail.com> wrote:
> On 20 August 2010 17:41, Peter Lind <peter.e.lind(a)gmail.com> wrote:
>> On 20 August 2010 17:10, Andy McKenzie <amckenzie4(a)gmail.com> wrote:
>>> Hey everyone,
>>>
>>>  I'm really not sure what's going on here:  basically, the bitwise
>>> NOT operator seems to simply not work.  Here's an example of what I
>>> see.
>>>
>>> ============Script============
>>>
>>> $ cat bintest2.php
>>>
>>> <?php
>>>
>>> $bin = 2;
>>> $notbin = ~$bin;
>>>
>>> echo "Bin: " . decbin($bin) . "  !bin:  " . decbin($notbin) . "\n";
>>> echo "Bin: $bin  !bin:  $notbin\n";
>>>
>>>
>>> ?>
>>> =============================
>>>
>>>
>>> ============Output============
>>>
>>> $ php bintest2.php
>>> Bin: 10  !bin:  11111111111111111111111111111101
>>> Bin: 2  !bin:  -3
>>>
>>> =============================
>>>
>>>
>>> Obviously that's not the expected response.  I expect to get something
>>> more like this:
>>>
>>> Bin: 10  !bin:  01
>>> Bin: 2  !bin:  1
>>>
>>>
>>> Can anyone shed some light on this for me?  The server is running an
>>> old version of OpenSUSE, and php --version returns:
>>>
>>
>> You probably need to read up on computer architechture and CS theory -
>> the ~ operator works fine, your understanding does not. What you're
>> looking at is the following:
>>
>> $bin = 2 = 00000000000000000000000000000010 (64 bit number)
>
> 32-bit number, as Colin pointed out.
>
> Peter
>
> --
> <hype>
> WWW: http://plphp.dk / http://plind.dk
> LinkedIn: http://www.linkedin.com/in/plind
> BeWelcome/Couchsurfing: Fake51
> Twitter: http://twitter.com/kafe15
> </hype>
>