基本概念:
真值:作为有符号位的机器数来说,因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。(也就是我们人类所能使用的数字。)
1.原码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.
a) [+1]=[0000 0001](原)
[-1]=[1000 0001](原)
2.反码:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
a) [+1]=[0000 0001](原)=[0000 0001](反)
[-1]=[1000 0001](原)=[1111 1110](反)
b) 如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.
3.补码:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
a) [+1]=[0000 0001](原)=[0000 0001](反)=[0000 0001](补)
[-1]=[1000 0001](原)=[1111 1110](反)=[1111 1111](补)
b) 对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
对于有符号而言:
1.二进制的最高位是符号位:0表示正数;1表示负数。
2.正数的原码、反码、补码都一样。
3.负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)。
4.负数的补码=它的反码+1
5. 0的反码、补码都是0
6.PHP没有无符号数,换言之,PHP中的数都是有符号的。
7.在计算机运算的时候,都是以补码的方式来运算的。
————————————————————————————2016.11.19手动分割线好累————————————————————————————————————
l 二进制的三个重要概念
1. 原码:用二进制表示一个数,这个码就是原码。
1-> 原码 00000000 00000000 00000000 00000001
5-> 原码 00000000 00000000 00000000 00000101
上述原码计算=1*20+0*21+1*22=5
2. 反码、补码:
负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)
举例:
-1的原码:10000000 0000000000000000 00000001
-1的反码: 11111111 1111111111111111 11111110
-1的补码:11111111 1111111111111111 11111111
3. 在计算机运算的时候,都是以补码的方式来运算
这句话的意思就是,不管一个数是正数还是负数,都要被转成补码,然后进行运算。
l 位运算一览表
例子 | 名称 | 结果 |
$a & $b | And (按位与) | 将把$a和$b中都为1的位设为1 |
$a | $b | Or (按位或) | 将把$a或者$b中为1的位设为1 |
$a ^ $b | Xor (按位异或) | 将把$a和$b中不同的位设为1 |
~ $a | Not (按位非) | 将$a中为0的位设为1,反之亦然 |
$a << $b | Shift left (左移) | 将$a中的位向左移动$b次 (每一次移动都表示“乘以2”) |
$a >> $b | Shift right (右移) | 将$a中的位向右移动$b次 (每一次移动都表示“除以2”) |
1. PHP中有4个位运算,分辨是“按位与&、按位或|、按位异或^、按位取反~”,他们的运算规则是:
按位与&:两位全为1,结果为1;
按位或|:两位有一个为1,结果为1;
按位异或^:两位一个为0,一个为1,结果为1;
按位取反~:0->1,1->0
2. PHP中有移位运算符:
>>、<<算术右移或算术左移,运算规则是:
算术右移:地位溢出,符号位不变,并用符号位补溢出的高位。
算术左移:符号位不变,低位补0
l 练习:
1. ~2=?
步骤:
先找到2的补码
正数的原码、反码、补码都一样:
2-> 00000000 0000000000000000 00000010
~2-> 11111111 1111111111111111 11111101
补码->反码->原码
反码:11111111 1111111111111111 11111100
原码:10000000 0000000000000000 00000011
所以~2=-3
2. ~-5=?
步骤:
-5的原码
-5-> 100000000 00000000000000000 00000101
原码->反码->补码
反码-5-> 1111111111111111 11111111 11111010
补码-5-> 1111111111111111 11111111 11111011
~-5-> 00000000 0000000000000000 00000100
补码->反码->原码:因为是正数,所以原码、反码和补码都一样
所以~-5=4
3. 2&3=?
步骤
首先找到2和3的补码
2原码-> 0000000000000000 00000000 00000010
3原码-> 0000000000000000 00000000 00000011
正数的原码、反码和补码都一样
2&3:
2-> 00000000 0000000000000000 00000010
3-> 00000000 0000000000000000 00000011
2&3-> 0000000000000000 00000000 00000010
所以2$3=2
4. 2|3=?
步骤:
先找到2和3的补码
2原码-> 0000000000000000 00000000 00000010
3原码-> 0000000000000000 00000000 00000011
正数的原码、反码和补码都一样
2|3=
2-> 00000000 0000000000000000 00000010
3-> 00000000 0000000000000000 00000011
2|3-> 00000000 0000000000000000 00000011
所以2|3=3
5. 2^3=?
步骤:
先找到2和3的补码
2原码-> 0000000000000000 00000000 00000010
3原码-> 0000000000000000 00000000 00000011
正数的原码、反码和补码都一样
2^3=
2-> 00000000 0000000000000000 00000010
3-> 00000000 0000000000000000 00000011
2|3-> 00000000 0000000000000000 00000001
所以2^3=1
l 位移运算
1. 运算的规则:
算术右移:低位溢出,符号位不变,并用符号位补溢出的高位
算术左移:符号位不变,低位补0
2. $a=1>>2
1的原码->00000000000000000 000000000 00000001
1>>2
00000000 00000000 00000000000000000
$a=0
3. $a=-1>>2
-1的原码-> 1000000000000000 00000000 00000001
-1的反码-> 1111111111111111 11111111 11111110
-1的补码-> 1111111111111111 11111111 11111111
-1>>2
111111111 11111111 1111111111111111(补码)
反码-> 11111111 1111111111111111 11111110
原码-> 1000000000000000 00000000 00000001
$a=-1
4. $a=1<<2
1的原码-> 0000000000000000 00000000 00000001
1<<2-> 00000000 0000000000000000 00000100
$a=4
5. $a=-1<<2
-1的原码->1000000000000000 00000000 00000001
-1的反码->1111111111111111 11111111 11111110
-1的补码->1111111111111111 11111111 11111111
-1<<2 ->1111111111111111 1111111 11111100
$a=-4