我们先了解一下位异或的运算法则吧:
1、a^b = b^a。
2、(a^b)^c = a^(b^c)。
3、a^b^a = b。
对于一个任意一个数 n,它有几个特殊的性质:
1、0^n = n。
2、n^n = 0。
3、1^n = !n。(即 n==0 时,则所得的值为真,当 n != 0,所得值为 0,即为假)
按位异或的 3 个特点:
(1) 0^0=0,0^1=1 0 异或任何数=任何数
(2) 1^0=1,1^1=0 1 异或任何数 = 任何数取反
(3) 任何数异或自己=把自己置 0
/*
手册资料:
位运算符
位运算符允许对整型数中指定的位进行置位。如果左右参数都是字符串,则位运算符将操作字符的 ASCII 值
$a ^ $b Xor (按位异或) 将把 $a 和 $b 中不同的位设为 1
*/
^(按位异或)的运算实例
#数字之间位运算
echo 12 ^ 9; // 输出为 '5'
#字符串之间位运算
echo "12" ^ "9"; // 输出退格字符(ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // 输出 ascii 值 #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // 输出 1
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // 输出 1
// ((int)"2") ^ 3 == 1
分析:在定义中我们可以知道,位运算符允许对 “整型” 中指定的位进行置位。但是也不仅仅只是支持 “整数”, 还支持字符串,不过如果左右参数都是字符串,则位运算符将操作 “字符的 ASCII 值”, 也就是如果是字符串,将转变成字符相应的 ASCII 然后再进行操作.
#对与字符串操作,根据上面分析,原理总结如下:
$aa= 'a'^'b';
$bb= chr(ord('a')^ord('b'));
var_dump($aa);
var_dump($bb);
#以上两种写法结果是一样的
按位异或的几个常见用途:
(1) 使某些特定的位翻转
例如对数 10100001 的第 2 位和第 3 位翻转,则可以将该数与 00000110 进行按位异或运算。
10100001^00000110 = 10100111
(2) 实现两个值的交换,而不必使用临时变量。
例如交换两个整数 a=10100001,b=00000110 的值,可通过下列语句实现:
a = a^b; //a=10100111
b = b^a; //b=10100001
a = a^b; //a=00000110
(3) 在汇编语言中经常用于将变量置零:
xor a,a
(4) 快速判断两个值是否相等
举例 1: 判断两个整数 a,b 是否相等,则可通过下列语句实现:
return ((a ^ b) == 0)
5 应用通式:
对两个表达式执行按位异或。
result = expression1 ^ expression2
参数 result 任何变量。expression1 任何表达式 ^ expression2 任何表达式。
说明
^ 运算符查看两个表达式的二进制表示法的值,并执行按位异或。该操作的结果如下所示:
0101 (expression1) 1100 (expression2)----1001 (结果) 当且仅当只有一个表达式的某位上为 1 时,结果的该位才为 1。否则结果的该位为 0。 只能用于整数
位运算
- 计算机里面所有的信息都是整数,所有的整数都可以表示成二进制的,实际上计算机只认识二进制的. 位运算就是二进制整数运算啦.
- 位运算时把数字用二进制表示之后,对每一位上 0 或者 1 的运算。理解位运算的第一步是理解二进制。二进制是指数字的每一位都是 0 或者 1. 比如十进制的 2 转化为二进制之后就是 10。
- 其实二进制的运算并不是很难掌握,因为位运算总共只有 5 种运算:与、或、异或、左移、右移。如下表:
与(&) | 0 & 0 = 0 | 1 & 0 = 0 | 0 & 1 = 0 | 1 & 1 = 1 |
或(|) | 0 | 0 = 0 | 1 | 0 = 1 | 0 | 1 = 1 | 1 | 1 = 1 |
异或(^) | 0 ^ 0 = 0 | 1 ^ 0 = 1 | 0 ^ 1 = 1 | 1 ^ 1 = 0 |
位取反(~) | ~$m | | | |
向左移位(<<) | $m << $n | | | |
向右移位(>>) | $m >> $n | | | |
小提示
正数的原码,反码、补码都是一样的,负数不一样
原码:数字的 8 位 二进制,符号位(第一位)为 0 表示正数,为 1 表示负数
反码:正数反码与原码一样,负数的反码是符号位 1 不变,整数的每一位二进制数位求反,得到反码
补码:正数补码与原码一样,负数反码的符号位 1 不变,按位取反,末尾(最低位)加 1;计算机中的运算都是以补码的形式运算的,存储也是补码
补码的特性:
1、一个负整数(或原码)与其补数(或补码)相加,和为模。
2、对一个整数的补码再求补码,等于该整数自身。
3、补码的正零与负零表示方法相同。
对比
含义 | php | C 语言 | Java |
按位与 | $a & $b | a & b | a & b |
$a | $b | a | b | a | b | |
按位异或 | $a ^ $b | a ^ b | a ^ b |
按位取反 | ~$m | ~a | ~a |
左移 | $m << $n | a << b | a << b |
带符号右移 | $m >> $n | a >> b | a >> b |
无符号右移 | a>>> b |