2013-08-25 6 views
0

Рассмотрим:Неожиданный результат операции побитовое

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

Я бы ожидать, что обратная 1100 быть либо 0011 (прямой) или 11110011 (весь байт). Это даст результат либо 3, либо 243. Откуда приходит -13?

Опять же, для хорошей меры, еще один неожиданный результат того же типа и объяснения:

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

Почему -7?

+3

Почему вы щадящие из минус в показанных результатах?Целые числа в PHP не просто занимают байты, а обычно 32 или 64-битное слово и подписываются. – mario

+0

Я даже не заметил знаки минуса! Я на самом деле копирую это из более чем идеальной среды. Благодарю. – dotancohen

+2

http://en.wikipedia.org/wiki/Two%27s_complement – devnull

ответ

1

Посмотрите на этот код:

<?php 
$val = 6; 

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

Он печатает

6 = 110 
-7 = 11111111111111111111111111111001 

Сначала у вас есть 110. Как m y php использует 32 бита, после инвертирования всех бит мы получаем это огромное количество. Поскольку 1-й бит равен 1, php интерпретирует его как отрицательное значение, сохраняя его, используя представление с двумя дополнениями. Для того, чтобы выяснить, модуль отрицательного значения, сохраняются в этих обозначениях мы

  1. инвертировать цифр:
  1. добавьте к результату:

, который дает нам 7

Таким образом, значение -7

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

1

Почему -7?

6 является 00000000000000000000000000000110, так ~6 является ~00000000000000000000000000000110, и это равно 11111111111111111111111111111001. Поскольку используется подписанный тип данных, первый бит указывает, является ли число положительным или отрицательным (положительное = 0 и отрицательное = 1). Поскольку это Two's complement, вы должны преобразовать двоичное число в десятичный, используя этот способ:

  1. Инвертировать двоичное число. Вы получаете 00000000000000000000000000000110
  2. Преобразование 00000000000000000000000000000110 (положительное двоичное число) в десятичное число. Вы получаете 6
  3. Добавить 6 с одним: вы получаете 7
  4. Сделать отрицательным: Вы получаете -7
Смежные вопросы