0

Consider:

php > $a = 12; // 1100
php > echo ~$a;
-13

I would expect the inverse of 1100 to be either 0011 (direct) or 11110011 (an entire byte). That would give a result to either 3 or 243. Whence cometh -13?

Again, for good measure, another unexpected result of the same type and explanation:

php > $b =  6; // 0110
php > echo ~$b;
-7

Why -7?

dotancohen
  • 30,064
  • 36
  • 138
  • 197
  • 3
    Why are you sparing out the minus in the shown results? Integers in PHP do not just occupy a byte, but usually a 32 or 64 bit word, and are signed. – mario Aug 25 '13 at 16:36
  • I didn't even notice the minus signs there! I'm actually copying this from a less-than-ideal environment. Thanks. – dotancohen Aug 25 '13 at 16:38
  • 2
    http://en.wikipedia.org/wiki/Two%27s_complement – devnull Aug 25 '13 at 16:39
  • AND the result with `0xf` (`1111`) so you get the answer you expect: `echo ~$b & 0xf`, it will cut the first 4 bits for you. –  Aug 25 '13 at 16:52

2 Answers2

1

Why -7?

6 is 00000000000000000000000000000110, so ~6 is ~00000000000000000000000000000110, and that's equal to 11111111111111111111111111111001. Because a signed datatype is used, the first bit indicates whether the number is positive or negative (positive = 0 and negative = 1). Because it is Two's complement, you should convert the binary number to decimal using this way:

  1. Invert the binary number. You get 00000000000000000000000000000110
  2. Convert 00000000000000000000000000000110 (a positive binary number) to a decimal number. You get 6
  3. Add 6 up with one: you get 7
  4. Make it negative: you get -7
ProgramFOX
  • 6,131
  • 11
  • 45
  • 51
1

Look at this code:

<?php
$val = 6;

print "$val = ".decbin($val);
print "\n";
$val = ~$val;
print "$val = ".decbin($val);

It prints

6 = 110
-7 = 11111111111111111111111111111001

At first you have 110. As my php uses 32 bits, after inverting all the bits, we get this huge number. As the 1-st bit is 1, php interprets it as a negative value, stored, using two's-complement representation. To find out, the modulus of the negative value, stored in this notation, we

  1. invert the digits:

110

  1. add one to the result:

111

which gives us 7

So, the value is -7

http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html

user4035
  • 22,508
  • 11
  • 59
  • 94