【问题标题】:Unexpected bitwise operation result [duplicate]意外的按位运算结果[重复]
【发布时间】:2013-08-28 04:18:33
【问题描述】:

考虑:

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

我希望1100 的倒数是0011(直接)或11110011(整个字节)。这会给3243 一个结果。 -13哪里来的?

再次,为了更好地衡量,另一个相同类型和解释的意外结果:

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

为什么是-7

【问题讨论】:

  • 为什么要在显示的结果中省略减号? PHP 中的整数不只是占用一个字节,通常是一个 32 位或 64 位的字,并且是有符号的。
  • 我什至没有注意到那里的减号!我实际上是从一个不太理想的环境中复制它的。谢谢。
  • 将结果与0xf (1111) 相结合,因此您将得到您期望的答案:echo ~$b & 0xf,它将为您剪切前 4 位。

标签: php bit-manipulation


【解决方案1】:

看看这段代码:

<?php
$val = 6;

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

打印出来

6 = 110
-7 = 11111111111111111111111111111001

起初你有 110。由于我的 php 使用 32 位,在反转所有位之后,我们得到了这个巨大的数字。由于第 1 位为 1,php 将其解释为负值,使用二进制补码表示存储。为了找出负值的模,存储在这个符号中,我们

  1. 反转数字:

110

  1. 在结果中加一:

111

这给了我们 7

所以,值为-7

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

【讨论】:

    【解决方案2】:

    为什么是-7?

    600000000000000000000000000000110,所以~6~00000000000000000000000000000110,等于11111111111111111111111111111001。因为使用有符号数据类型,所以第一位指示数字是正数还是负数(正数 = 0 和负数 = 1)。因为是Two's complement,所以应该用这种方式将二进制数转换为十进制数:

    1. 反转二进制数。你得到00000000000000000000000000000110
    2. 00000000000000000000000000000110(正二进制数)转换为十进制数。你得到6
    3. 加一个6:你得到7
    4. 让它变成负数:你得到-7

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-01
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-12-11
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      相关资源
      最近更新 更多