Why does this code return -1 ?
$a = 0; echo ~$a;
Isn\'t not suppose to revert the bits ?
That zero is actually being represented by 32 zero bits, as PHP integer types are 32-bit signed integers, and not single bits:
0000 0000 0000 0000 0000 0000 0000 0000
So bitwise NOT flips all of them, resulting in the two's complement of -1 (with the leftmost one representing the sign):
1111 1111 1111 1111 1111 1111 1111 1111
The integers are stored in 2's compliment form .
this form can be outline ad follows :
1) If the number to be stored is an positive value then its binary value is stored
eg $val = 5 ;
here $val contains ordiary binary equivlent of 5 = 0101 //number of bits depends on specifics
2) if you are storing negative of an number say -5 , then the twos compliment s stored
$val = -5;
here first 2's compliment of 5 is found out ie, simply 1's compliment of 5 + 1
~ 0101 = 1010
tnen add 1
1010 +
1
-----
1011
and this 1011 gets stored in $val .
in same way , $val=0 ; 00 is stored
~$val => 11 which is the equalient of -2 in 2's compliment form
and finally , if you observe carefully , you may ask ,
so how could I represent 11 ? for its binary values is 1011 that clashes with -5's value in 2's comp ?
the answer lies in number of bits used to represent number.
in 2's complimwent form if there are n bits then you can represent only values from
-2^(n-1) to 2^(n-1) -1 ;
If you set all the bits on a two's complement integer then you get −1.
Let me illustrate with a (very tiny) two-bit signed integer using two's complement:
00 → 0
01 → 1
10 → −2
11 → −1
This is just counting up from 0, past the overflow from 1 to −2 and ending at −1. As you can see, if you clear all bits you get 0, if you set them all, you get −1 (regardless of how wide the integer is).
(Mind you, people using BASIC knew this already, as there were no boolean operators and things work just as well with bitwise operators, except that True is −1 instead of 1.)
Yes it should, and on the two's complement number system, a number with all bits set equals to -1 and since 0 has all bit unset, ~$a will have all its bit set.
So the code is behaving as expected.