位运算符
十进制与二进制
小例子:10(二进制)—> 十进制
10 = 0 * 2^0 + 1 * 2^1 = 2
十进制转换为二进制, 大家肯定也会,这里不多说了。
但是这里有一点是需要注意的就是计算机对于数字的表示问题。
机器数与机器数真值
-
机器数
一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用机器数的最高位存放符号,正数为0,负数为1。比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是0000 0011。如果是 -3 ,就是 1000 0011 。
那么,这里的 0000 0011 和 1000 0011 就是机器数。
-
机器数真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 1000 0011,其最高位1代表负,其真正数值是 -3,而不是形式值131(1000 0011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
原码、反码、补码
对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式。
-
原码:是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。即机器数真值。(根据数据类型的不同,其他位存放的二进制的绝对值需要在前补不同长度的0)
-
反码:正数的反码还是等于原码;负数的反码就是他的原码除符号位外,按位取反。
- 补码:正数的补码等于他的原码;负数的补码等于它的反码+1。(这只是一种算补码的方式,多数书对于补码就是这句话)
注意:计算机中数字以补码储存,因为原码和反码计算不准确,而补码是准确的。 所以程序中的位运算都是在补码上展开的,而最后在屏幕上显示的是补码经过位运算后的二进制,在给定数据类型后进行截取,然后经过补码->反码->原码,最后显示的机器数真值。
位运算注意点
- “<<” 符号 :在一定范围内,每向左移1位,相当于 ×2,有时进行左移时,会出现负数变正数的情况
“>>” 符号 :在一定范围内,每向右移1位,相当于 /2,超过这个范围就有可能正数变负数,或负数变正数,所谓物极必反 - 二进制数 & 1 等价于 这二进制数对应的十进制数 %2
- n & (n-1):二进制数字 n 最右边的 1 变成 0 ,其余不变。(可以用来计算二进制中 1 的个数)
- n & (-n):得到二进制数字 n 中最低位的 1。
- (n ^ m)^ m = n ;(n ^ m)^ n = m
- && 、|| :短路与、短路或,可以用于判断语句,代替if
- A 和 B 两数相乘的时候我们如何利用加法和位运算来模拟,其实就是将 B 二进制展开,如果 B 的二进制表示下第 i 位为 1,那么这一位对最后结果的贡献就是 A*(1<<i) ,即 A<<i 。