C语言的位运算详解

楔子

2021-1-21日,天气阴
     我像往常一样起床、开始写代码,突然我感到一种莫名的心情在我心中翻涌,虽不强烈,但也让我有了点与代码无关的念头。

1、位运算

位运算说明:

  • 按位与& : 两个全为1,结果为1,否则为0
  • 按位或| :两个有一个为1,结果为1,否则为0
  • 按位异或 ^:两个一个为0,一个为1,结果为1,否则为0
  • 按位取反 ~: 0 -> 1,1->0
  • 按位左移<<:将一个运算对象的各二进制位全部左移若干位,左边的二进制位丢弃,右边的补0
  • 按位右移>>:将一个运算对象的各二进制为全部右移若干位,右边的二进制位全部丢弃,左边负数补1,正数补0

C语言的原码,反码,补码

  • 二进制的最高位是符号位:0表示正数,1表示负数
  • 正数的原码,反码,补码都一样(三码合一)
  • 负数的反码 = 它的原码符号位不变,其它为取反(0->1,1->0)
  • 负数的补码 = 它的反码+1
  • 0的反码,补码都是0
  • 在计算机运算的时候,都是以补码的方式来运算的,它可以把正数和负数统一起来

运算表
C语言的位运算详解_第1张图片
案例:

  • 求出~2的值
	//在计算机运算的时候,都是以补码的方式来计算的,所以先得到它的补码
		//2是正数,所以他是三码合一,2默认是int类型的,为4个字节
		2的原码\反码\补码: 00000000 00000000 00000000 00000010 => 2
		//这里得到的是一个补码
	 按位取反~211111111 11111111 11111111 11111101  //按位取反和反码不是一个概念
	 	//我们需要将什么的补码转成原码
	 	补码-1=>反码: 11111111 11111111 11111111 11111100
	 	反码符号位不变,其他位取反=>原码:10000000 00000000 00000000 00000011  => -3
	 	最后得到的结果为~2 = -3
  • 求出2&-3的值
	//先得到2和-3的补码
	2是正数,所以三码合一
	2的补码:00000000 00000000 00000000 00000010
	
	-3的原码:10000000 00000000 00000000 00000011
	-3的反码:11111111 11111111 11111111 11111100
	-3的补码:11111111 11111111 11111111 11111101

	2&-3
	2的补码:00000000 00000000 00000000 00000010
   -3的补码:11111111 11111111 11111111 11111101
 2&-3的补码:00000000 00000000 00000000 00000000 = > 0
	
	
  • 求-1<<2的值(左移)
	//先得到-1的补码
	-1的原码:10000000 00000000 00000000 00000001
	-1的反码:11111111 11111111 11111111 11111110
	-1的补码:11111111 11111111 11111111 11111111

       -111111111 11111111 11111111 11111111
-1左移211111111 11111111 11111111 11111111	
	//左移:左边的二进制位全部丢弃,右边的补0
	-1<<2补码:11111111 11111111 11111111 11111100
	-1<<2反码:11111111 11111111 11111111 11111011
	-1<<2原码:10000000 00000000 00000000 00000100 = >-4
  • 求-1>>2的值 (右移)
	//先得到-1的原码
	-1的原码:10000000 00000000 00000000 00000001
	-1的反码:11111111 11111111 11111111 11111110
	-1的补码:11111111 11111111 11111111 11111111
	//右移2位,移除最右边的两个进制位,因为是负数,所以在左边补1,如果是正数则补0
	-1>>2的补码:11111111 11111111 11111111 11111111

2、细节说明

以下是我在实际使用过程中发现的一些问题

  • 在进行~运算的时候,对负数的补码进行取反操作后得到的数就是运算的结果,不需要再将得到的数转换成原码,例如:
~-5
-5原码:10000000 00000000 00000000 00000101

-5的反码:11111111 11111111 11111111 11111010

-5的补码:11111111 11111111 11111111 11111011

~-500000000 00000000 00000000 00000100 

如果再将取反的结果进行反码,原码的转换就得不到我们想要的结果

  • 如果是正数的的话,在对其补码进行取反操作后得到的数还需要进行到反码->原码的转换,例如
~5的值

原码、反码、补码(正数三码合一):00000000 00000000 00000000 00000101

~5(取反操作后的补码):11111111 11111111 11111111 11111010

~5的反码:11111111 11111111 11111111 11111001

~5的原码:100000000 00000000 00000000 00000110 = -6

你可能感兴趣的:(C语言,笔记,c语言,补码)