免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1253 | 回复: 0
打印 上一主题 下一主题

E_ALL & ~E_NOTICE 与 E_ALL ^ E_NOTICE [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 08:54 |只看该作者 |倒序浏览

在某个论坛上发现了三年前的有趣话题, 哈哈哈哈哈哈, 希望它们看过"数据结构"教科书,也许它们上学时有这本, 也许它们至今还珍藏并且从未看过

我觉得这话题, 的确会有一部分人会理解, 但是我希望给不理解的那部分人看的, 也许这问题本身就很粗浅, 但是我们都高估了计算机专业科班出身的那群孩子的专业知识

error_reporting(E_ALL & ~E_NOTICE);
error_reporting(E_ALL ^ E_NOTICE);

要理解这个问题, 得从位运算的基础说起

PHP中, 整形为32个位, 换句话说,

1 = 00000000000000000000000000000001
~1 = 11111111111111111111111111111110

其实对于 E_NOTICE 使用 & ~ 或者 ^ 的结果, 出现问题的几率是0, 因为 E_NOTICE 的确是包含在 E_ALL 中
那我们换个常量来用看看, E_STRICT 在 PHP 5.0 中被定义, 而它的特殊性, 导致它并没有被定义在 E_ALL 中,

假设某个童鞋写了一个程序, 而我们的程序作者同学对 E_STRICT 不包含在 E_ALL 中并不知情
error_reporting(E_ALL ^ E_STRICT);
这时问题就出现了, 假定当前PHP版本为5.2, 这时

E_ALL = 6143 = 00000000000000000001011111111111
E_STRICT = 2048 = 00000000000000000000100000000000

这里可以看出来, 6143的第12位为0, 而2048为1,
###########################################
我们来说^是什么, ^的作用是: 当 操作数A 和 操作数B 中当前位不同时, 返回结果的当前位设为1, 反过来理解就是, 当 A或B 中当前位相同时, 返回的结果的当前位为0

而我们的作者童鞋正是希望它的反向结果,也就是由于A/B中当前位相同,所以得到0,相当于去掉这个2048,事与愿违的是,,

由于6143中不包含2048, 所以6143和2048的每一位都不同, 所以我们的6143被填上了第12位的1, 变成了8191, 而不是预期的去掉第12位的1, 而作者的意图很明显的是希望去掉它, 很遗憾的是作者并不知道它本来就不在其中
程序运行的结果就是所有的E_STRICT错误被展示给所有访问者欣赏
###########################################
那么我们再看 & ~的结果
首先说, &的含义是 将 A 和 B 中当前位都为1的位设为1, 反过来就是 A 或 B 中任意一个的当前位不为1, 当前位的结果都是 0
而~的含义是将操作数种所有的位翻转过来, 以前是1的变成0, 以前是0的变成1, 所以:

~2048 = 11111111111111111111011111111111

那么接下来由于 6143 的第12位为0, 被翻转的2048中第12位也为0, 而 & 只有在 A 和 B 的当前位皆为1时才将结果范围为1,其他皆为0, 那么第12位仍然保持0, 其他位不同的为0, 此时~2048中除第12位其他皆为1, 在6143中原有的为1的位保持不变,其他不同的变成了0,得到的结果仍然是6143
###########################################
至此我们得到一个结论

使用 A^B 希望将B排除在外, 希望这个条件成立, 只有在A中绝对包含B的情况下才能实现,而A中不包含B的情况下,相当于A加上B, 也就是说 ^ 在A中有B时去掉B,在A中没有B时加上B,是这么个作用

而使用 A&~B可以在无论是否已知A中是否包含B的情况下都可以无条件的让结果中不包含B, 等于说安全的从A中去掉B
###########################################
捎带介绍下 | , 它的作用是 A 和 B 中任意一个当前位为1的情况下, 结果的当前位即为1 , 这相当于 无论中 A中是否存在B, 都可以安全的添加B,不会让结果溢出
###########################################
简易理解方式:

使用 A ^ B : A中有B就去掉, A中没有B就加上
使用 A & B : 返回双方都包含的部分, 可用于判断某个或某些位是否存在
使用 A & ~B : A中有没有B都去掉B,不影响其他位
使用 A | B : A中有没有B都加上B, 不影响其他位
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP