【位运算】必知必会:二进制位的原码反码补码转换 以及 按位与&、按位或|、异或^

二进制位的原码反码补码转换 以及 按位与&、按位或|、异或^

  • 一、二进制位的原码、反码、补码转换
      • 1.机器数
      • 2.原码
      • 3.反码
      • 4.补码
  • 二、按位与&、按位或|、异或^

最近在练习LeetCode上的算法题,遇到了位运算求解的问题,作以复习总结。

一、二进制位的原码、反码、补码转换

在计算机当中都是使用补码来进行计算和存储的。
反码解决了正确计算负数问题;
补码很好的解决了反码 负数不能跨零计算的弊端;
并且补码还可以记录一个特殊的值 -128,这个数据在 1 个字节下是没有原码和反码。

正数的原码反码补码相同;
负数的原码—>反码: 符号位不变,其余各位取反;
负数的反码—>补码: 反码加上1(相当于将原码数值位取反然后在最低位加1) ;


1.机器数

机器数:一个数在计算机中的表示形式是二进制;
机器数通常是带有符号的(指有正数和负数之分),计算机用最高位存放符号,这个 bit 一般叫做符号位正数的符号位为 0, 负数的符号位为 1

比如,十进制中的数 +7 ,计算机字长为8位,
	 转换成二进制就是 0 0 0 0 0 1 1 1(一个 byte 有 8bit,有效的取值范围是 -128 ~ +127)。
      如果是 -7 ,就是1 0 0 0 0 1 1 1。

计算机底层使用二进制形式的补码来计算和存储数据

一个存储的二进制码分原码、反码、补码!

2.原码

十进制数据的二进制表现形式就是原码,原码最左边的一个数字就是符号位,0为正,1为负。

左边第一位为符号位,其他位为数据位。

一个 byte 有 8bit,最大值是 0 1 1 1 1 1 1 1(+127),最小值是 1 1 1 1 1 1 1 1(-127)

在计算机中之所以使用二进制来表示原码是因为逻辑简单,对于电路来说只有开或者关两种状态,用二进制是在方便不过的了。

计算:

使用原码对正数进行计算不会有任何问题的。
但是如果是负数的话,那计算的结果就会大相径庭了。

例如 :5+2
	 0 0 0 0 0 1 0 1
	+        0 0 1 0
	-----------------
	 0 0 0 0 0 1 1 1
结果没问题,值为7.

如果是负数,-56 -1
	 1 0 1 1 1 0 0 0
	-              1
	 -----------------
	 1 0 1 1 0 1 1 1
显然结果不应该是-55!减一之后正确的结果应该是 -57(1 0 1 1 1 0 0 1)才对。

为了解决原码不能用于计算负数的这种问题,这时候,反码它出现了,作为负数的“计算的救星”。

计算规则是正数的反码不变和原码一致,负数的反码会在原码的基础上,高位的符号位不变,其他位取反( 1 变成 0 , 0 变为 1 )

3.反码

正数的反码是其本身(等于原码),负数的反码是符号位保持不变,其余位取反。反码的存在是为了正确计算负数,因为原码不能用于计算负数。

十进制数字 原码 反码
+0 0000 0000 0000 0000
-0 1000 0000 1111 1111
-1 1000 0001 1111 1110

负数计算
这时候,我们再来使用反码计算一下 -56 - 1 的结果。

-56 的原码是1 0 1 1 1 0 0 0,如果转成反码(符号位不变,其他位取反)

那么它的反码就是1 1 0 0 0 1 1 1

  1 1 0 0 0 1 1 1
 -              1
-----------------
  1 1 0 0 0 1 1 0

-56 -1 = -57,-57 的原码是1 0 1 1 1 0 0 1,转成反码刚好是1 1 0 0 0 1 1 0,刚好等于刚才我们算出的值。

跨零计算
不过反码也有它的 “ 软肋 ”,如果是负数跨零进行计算的话,计算得出的结果不对.

-3 + 5 来举例

-3 的原码是1 0 0 0 0 0 1 1,转成反码的话就是 1 1 1 1 1 1 0 0

 1 1 1 1 1 1 0 0
+        0 1 0 1  
-----------------
 0 0 0 0 0 0 0 1
把计算结果转成十进制就是 1,这结果显然不对。那么我们该怎么计算呢,这时候,作为反码的补充编码 —— 补码就出现了。

作为反码的补充编码 —— 补码就出现了。

4.补码

正数的补码是其本身,负数的补码等于其反码 +1。因为反码不能解决负数跨零(类似于 -6 + 7)的问题,所以补码出现了。

跨零计算
这时候,我们再来使用反码计算一下 -3 + 5 的结果。

-3 的原码是1 0 0 0 0 0 1 1,转成反码的话就是 1 1 1 1 1 1 0 0,再转成补码就是1 1 1 1 1 1 0 1

 1 1 1 1 1 1 0 1
+        0 1 0 1
----------------- 
 0 0 0 0 0 0 1 0
结果正确。

二、按位与&、按位或|、异或^

运算符 含义 运算规则 用途
& 位与 两个位都是1,结果为1,其他为0 1.判断奇偶数:用if ((a & 1) == 0) 代替 if (a % 2 == 0)来判断a是不是偶数;2.取余:让a对16进行取余,那么就可以让 a & 15
| 位或 两个位都是0,结果为0,其他为1
^ 位异或 同0异1:相同为0,不同为1 交换两个数:(a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a,a^0=a
~ 位非 0变1,1变0 求相反数: ~a + 1
<< 左移 向左移动,低位补零 做 * (2 ^ n)的运算
>> 右移 向右移动,高位补零,符号位按照原来数字的符号位不变 1.做 / (2 ^ n)的运算;2.求绝对值: a >> 31 == 0 ? a : (~a + 1)
>>> 无符号右移 向右移动,高位补零 -

下一篇有关于位运算实际使用的介绍!

你可能感兴趣的:(LeetCode算法刷题,操作系统,算法,windows)