2

Why does this code return -1 ?

$a = 0; 
echo ~$a;

Isn't not suppose to revert the bits ?

johnlemon
  • 20,761
  • 42
  • 119
  • 178
  • It does. In twos compliment, a bit field of all ones is -1. http://en.wikipedia.org/wiki/Two%27s_complement – GordonM Jan 09 '12 at 07:29

4 Answers4

8

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.)

Joey
  • 344,408
  • 85
  • 689
  • 683
  • 1
    "people using BASIC" I am officially too young to remember. – BoltClock Jan 09 '12 at 07:29
  • 1
    At least until Visual Basic 6 it was this way, if I remember correctly. VB.NET introduced short-circuiting `AndAlso` and `OrElse` as well as a boolean type. – Joey Jan 09 '12 at 07:41
5

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
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 4
    If you don't see why all one bits is -1, just ask yourself this: What do you get if you add 1 to it? Answer: It overflows and all the bits are zero. We have a name for the number that gives zero when you add one to it ... -1. – David Schwartz Jan 09 '12 at 07:22
  • 1
    David, this is true for two's complement, but not for sign bits or one's complement (at least not naïvely). Either option may be equally explainable from the point of someone not intimately knowing computers. – Joey Jan 09 '12 at 07:25
2

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.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
0

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 ;
Vijeenrosh P.W
  • 359
  • 1
  • 3
  • 8