php位操作
‘壹’ php 位运算中的按位取反到底什么意思
二进制 0变1 1变0
例如00000001按位取反后11111110
‘贰’ php位运算中为什么 'a'&1=0,而不是1,a的ascii码对应值是97,那不就是97&1=1吗
PHP 官方文档中, Bitwise Operator 中有一段话:
If both operands for the &, | and ^ operators are strings, then the operation will be performed on the ASCII values of the characters that make up the strings and the result will be a string. In all other cases, both operands will be converted to integers and the result will be an integer.
使用 &, | 还有 ^ 操作符的时候,只有操作符两边的值都是 string 的时候,才会使用 ASCII 去运算,返亩李毁回 string,其他的所有情况下,都会把值转换成迅备 int。
你问题中的运算并非两个值都是字符串,所以都要被转成 int 计算。intval( 'a' ); 的结果是0,所以相当扰喊于 0 & 1
‘叁’ php如何实现js的移位运算符
移位包括有符号左移(<<)、有符号右移(>>)、无符号右移(>>>),其中 js 支持三种移位,PHP只支持前两种移位(没查到第三种),恰好需要PHP进行无符号右移,此处实现一下。先看结果
将数字 $a 向右无符号移动 $n 位
[php] view plain
functionuright($a,$n)
{
$c=2147483647>>($n-1);
return$c&($a>>$n);
}
下面是这样做的理由
1、有符号右移的过程
2 >> 1
2在计算机中存储的二进制表示为
000000000 00000000 00000000 00000010
向右移动1位,高位补0
000000000 00000000 00000000 00000001
结果为1
-2 >> 1
负数的存储是以补码的方式存储的(相关知识自行了解),这里简单说明
符号位是 1,-2的表示为
100000000 00000000 00000000 00000010
补码:除符号位外,其他位按位取反,然后 + 1
11111111 11111111 11111111 11111101
11111111 11111111 11111111 11111110
向右移动1位,高位补1
11111111 11111111 11111111 11111111
结果为 -1(转换成10进制后)
注意:移位操作是按照计算机中实际存储的二进制形式进行移动的
2、无符号右移的过程
2 >> 1同上
-2 >> 1
补码右移1位,高位补 0
01111111 11111111 11111111 11111111
结果是 2147483647
无符号右移 n 位,即把所有位向右移动 n 位(有符号右移),然后把前 n 位变成 0。
要把前 n 位变成 0 ,只需要让其跟一个前 n 位是 0,后 32-n 位是 1 的数进行按位与就可以了。
构造前 n 位是 0 后 32-n 位是 1 的数:利用正数有符号右移高位补 0 实现,这里用 2147483647 这个正数实现(当然其他数也可以),这个数在计算机中的存储前面已经说了,是
01111111 11111111 11111111 11111111
利用这个数构造前 n 位是 0 的数,只需将其向右移动 n-1 位就行了
-2 无符号右移 2位的过程
-2右移2位:11111111 11111111 11111111 11111111
构造数: 00111111 11111111 11111111 11111111
按位与: 00111111 11111111 11111111 111111
‘肆’ PHP中的位运算符--Not(按位非),怎么在笔记本的键盘上输出
shift+1左边那个键
如果不行 那就是fn+shift+1左边那个键
‘伍’ php中两个整型数组能不能进行按位或运算(就像c语言和matlab的&运算符一样)举个例子吧,这
给你一个与运算的,或运算的直接改一下&=>||
functiona($ar,$br){
foreach($aras$key=>$value){
$cr[]=$value&$br[$key];
}
return$cr;
}
$ar=array(0,0,1,1);
$br=array(1,0,1,0);
print_r(a($ar,$br));
‘陆’ 位(bit)运算
一、二进制:所谓二进制就是逢二进一 (0,1), 因为使用二进制只有 0, 1 两个数,简单,易于电子方式实现 , 同时,通过0,1 组合可以表示任意一个数.
二进制有三个重要的概念:
1.原码
用二进制来表示一个数,这个码就是原码.
1 ------> 原码 00000000 0000000 0000000 00000101 = 1 2的零次方+0 2的一次方+1* 2的二次方=1+0+4=5
2.负数的反码=它的原码符号缺猛位不变,其它位取反(0->1,1->0)
反码(正数的反码和它的原码一样 , 负数反码 是 符号位不变其它位取反)
补码(正数的补码和它的原码一样,负数的补码是 它的反码+1)
举例
-1
-1的原码 10000000 00000000 00000000 00000001
-1的反码 11111111 11111111 11111111 11111110
-1 的补码 11111111 11111111 111111111 11111111
3. 在计算机运算的时候,都是以补码的方式来运算的
4+5=>计算机 4-5=4+(-5)
这句话意思就是,不管一个数是正数还是负数,都要被转成补码,然后进行运算.
位运算一览表:
该图的前面四个是位运算
其运算规则是:
按位与&:两位全为1,结果为1
按位或| : 两位有一个为1,结果为1
按位异或 ^ : 两位一个为0,一个为1,结果为1
按位取反 : 0->1 ,1->0
<h3>求解:~2=?</h3>
步骤 : 首先要求出 2的补码
2是正数 所以 原码=反码=补码
2 原码
00000000 00000000 00000000 00000010
~2
11111111 11111111 11111111 11111101 (补码)->原码
? 负数的 原码-》反码-》补码
11111111 11111111 11111111 11111101->
推出其反码 (对补码-1)
11111111 11111111 11111111 11111100
推出原码
10000000 00000000 00000000 0000011 -> -3
~-5=?
-5 的 补码找出来.
-5 原码 10000000 00000000 00000000 00000101
-5 反码 11111111 11111111 11111111 11111010
-5 补码 11111111 11111111 11111111 11111011
~-5取反 00000000 00000000 00000000 00000100 (补码)
4
3 的补码 00000000 00000000 00000000 00000011
2&3 00000000 00000000 00000000 00000010 [补码]
2 的补码 00000000 00000000 00000000 00000010
3 的补码 00000000 00000000 00000000 00000011
2^3 00000000 00000000 00000000 00000001
二:位移运算:在php 中位运算有两种 >> (右移) << (左移)
运算的规则是 :
算术右移:低位溢出,符号位不变,并用符号位补溢出的高位
算术左移: 符号位不变,低位补0
根闷宴据我们前面的规范,来完成几个案例
$a=1>>2;
1 的补码
00000000 00000000 00000000 00000001
1>>2
00000000 00000000 00000000 00000000
$b=-1>>2;
$c=1<<2;
1<<伏罩桥2
1的补码
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000100
‘柒’ 大牛! 【php 位运算】 -2&-3 等于-4 这个事怎么算出来的
你这样算
-2的补码 & -3的补码 =(1111 1110)2 & (1111 1101 )2 =(1111 1100)2
减一取反得原码 1111 1011 原码1000 0100
(1000 0100)2 =(-4)10
‘捌’ php中的运算符有哪些
A选项,看下图:
不用全部记住,记住平时比较常用的就行了,还有记住:算术运算符>关系运算符>逻辑运算符>赋值运算符。
(8)php位操作扩展阅读:
PHP 中的运算符分为:四则运算符、逻辑运算符、三目运算符和位运算符。
运算符优先级指定了两个表达式绑定得有多“紧密”。例如,表达式 1 + 5 * 3 的结果是 16 而不是 18 是因为乘号(“*”)的优先级比加号(“+”)高。
必要时可握枣以用括号来强制改变优先级。例如:(1 + 5) * 3 的值为 18。如果运算符优先级相同,则使用从左到右的左联顺序。
对字符串和数字进裤皮慎行加胡敬法运算。
请看这些例子:
x = 5 + 5; document.write(x); x = "5" + "5"; document.write(x); x = 5 + "5"; document.write(x); x = "5" + 5; document.write(x)。
x = 5 + 5; document.write(x); x = "5" + "5"; document.write(x); x = 5 + "5"; document.write(x); x = "5" + 5; document.write(x)。
‘玖’ PHP语言PHP语言里的位运算符&、|、^ 、~、〈〈 、〉〉这些符号我一个也不懂,希望高手给个全面的解释!拜
"&" 按位与运算
按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。
例如:9&5可写算式如下:
00001001 (9的二进制补码)
&00000101 (5的二进制补码)
00000001 (1的二进制补码)
<?php
$a = 9;
$b = 5;
echo sprintf("%b", $a&$b);
?>
"|" 按位或运算
按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
例如:9|5可写算式如下:
00001001
|00000101
00001101 (十进制为13)可见9|5=13
<?php
$a = 9;
$b = 5;
echo sprintf("%b", $a|$b)."\n"; //二进制
echo sprintf("%d", $a|$b)."\n"; //十进制
"^" 按位异或运算
按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下:
00001001
^00000101
00001100 (十进制为12)
<?php
$a = 9;
$b = 5;
echo sprintf("%b", $a^$b)."\n"; //二进制
echo sprintf("%d", $a^$b)."\n"; //十进制
"~" 求反运算
求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。
例如~9的运算为:
~(0000000000001001)结果为:1111111111110110
<?php
$a = 9;
$b = 5;
echo sprintf("%b", ~$a)."\n"; //二进制
"〈〈" 左移运算
左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。
例如:
a<<4
指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。
<?php
$a = 3;
$temp = $a<<4;
echo sprintf("%d", $temp)."\n"; //十进制
“>>” 右移运算
右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如:
设 a=48,
a>>4
表示把00110000右移为00000011(十进制3)。
应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
<?php
$a = 48;
$temp = $a>>4;
echo sprintf("%d", $temp)."\n"; //十进制
‘拾’ php 的位运算总结
php的位运算很少会用到,但是用处很大,
在有些算法中会用到,在权限管理中也会经常用到,
对于理解计算机的世界也会有一定的帮助,所以得把这些重要但不常用的东西总结一下记录一下。
提到位运算,避不开的是二进制。
因为位运算是直接在内存做操作和运算,相较与直接拿两个变量做运算符肯定是更快的。
很多地方把二进制这玩意说得很晦涩,现在来以最简单的方式来总结一下,当然只算 int 范围内的数算了,超过了这个范畴程序员还不如拿这时间去学点别的。
说完以上总结,再来解释下什么是二进制,网上大把,
但只要记住,int范围内的数也就是我们大部分需要用到的数,都可以用二进制来表示。
我们生活中用到的计数方式为十进制,由个数位满10进1,
然后再开始重新计算,等十位满9再加一时,百位加一,十位归零。
二进制则只有两个数字来表示就是0和1,满2进1。
由32个位组成,虽然只有32个位但已满足了我们正常的需求了
比如说1转换为2进制原码,由于1是正数所以符号位为0,
原码反码补码都一个样。
1的原码:00000000 00000000 00000000 00000001
因手懒,太多0太丑用+拼接,Ɔ* 8'代表8个0
2的原码:0* 8 0* 8 0* 8 0* 6 + 1 0,既然是二进制,
满2就得进1,最低位归0,向前加一。
再来解释下负数的原码反码和补码,就开始讲php的位运算了。
二进制复习完毕。下面开始讲讲php的位运算。
php一共有六种位运算,一种一种来讲。
可以这么理解,两个数的补码放在一起比较每个位(一共32个位),
可以得出另外一个数,这个数字的组成由比较的两位数字生成,
如果两个数的每个位数上的数字都等于1的话,
那得到的那个数的补码的同位为1,否则为0。
听着绕口,其实很简单,觉得还是比官网上的更容易让新手看懂
下面举例子:
首先来求-1和7的补码。7的原码就是补码。
两个补码都有了下面开始运算:
按照上面的说法, 每个位都有一样则 $a 的同等位则为1,刚好-1的补码和7的补码前面都不一样,就最后三位一样,所以刚好求得的 $a 的补码的最后三位是1而其他的都是0 ,刚好这个补码为正数,正好就是7。
其实就是和按位与相反,只要有1个为1,那就为1,如果都不为1,那就为0。
$a = -1|7 ;得出来的 $a 补码为32个1,但此时不能说 $a 就是-1,因为这只是补码,要转成原码再转成十进制数,补码-1,然后再翻转,再转出来,得到的其实也还是-1。
就是将这个数的补码全部翻转过来,包括符号位,0变1,1变0
取反的结果一定是整数变负数负数变正数,取正数的反时,
记得一定要从补码一步步转到原码再转成十进制数才是答案。
两个数的补码比较,同等位上的两数比较
,不一样时,则答案的补码的同位则为1,否则为0。
往左移符号位被挤走右边0补充,往右移动,符号位不动,
高位以符号位补充。二进制世界里往左移动其实是相当于乘以了2,
右移相当于除以了2。
不吹牛逼的说,这应该是互联网上最容易理解的php位运算的解释和二进制的解释了。
原文链接: php的位运算总结-PHP