巧妙运用C语言位运算

合集下载

c语言的位操作

c语言的位操作

c语⾔的位操作c语⾔的位操作最常⽤的地⽅就是⽤在对寄存器的写值上。

⼀.基本的⼀些概念 1.位与:&操作:1 & 1 = 1; 1 & 0 = 0; 0 & 0 = 0;特点:只有全是1的时候才是1,其他情况都是0.总结:任何数和0位与就是0,和1位与没有变化,所以位与常⽤在清零上(清零⽤位与)。

2.位或:|操作:1 | 1 = 1; 1 | 0 = 1; 0 | 0 = 0;特点:只有全0的时候才是0,其他情况都是1.总结:任何数和1位或就是1,和0位或没有变化,所以位或常⽤在置1上(置1⽤位或)。

3.位取反:~操作:~1 = 0; ~0 = 1;特点:1取反为0,0取反为1. 4.位异或:^操作:1 ^ 1 = 0; 1 ^ 0 = 1; 0 ^ 1 = 1; 0 ^ 0 = 0;特点:相同为0,不同为1.总结:任何数和1位异或会取反,和0异或没有变化(特定位要取反就⽤位异或)。

5.左移(<<)和右移(>>)操作的时候要考虑有符号数(signed number)和⽆符号数(unsigned number)。

对于有符号数:左移的时候右侧补0;右移的时候左侧补符号位(正数符号位为0,则补0;负数符号位为1,则补1).对于⽆符号数:左移的时候右侧补0;右移的时候左侧也是补0.注意:我们对寄存器进⾏赋值的时候⽤的都是⽆符号的数⼆.与逻辑运算的区别 1.逻辑运算的基本符号:逻辑与(&&) 逻辑或(||) 逻辑取反(!) 2.我们需要注意的地⽅就是:位操作中只有1和0;逻辑操作的中⾮0代表是真(1),0就代表是假(0) 3.运算的时候,位运算是把数字拆为⼀位⼀位的进⾏运算的;逻辑运算是把数字作为⼀个整体进⾏运算的,但是他们运算的基本操作和位运算⼀致(譬如:1 && 1 = 1, 0 && 1 = 0 等等)。

C语言中的位运算的技巧

C语言中的位运算的技巧

C语⾔中的位运算的技巧⼀、位运算实例1、⽤⼀个表达式,判断⼀个数X是否是2的N次⽅(2,4,8,16.....),不可⽤循环语句。

X:2,4,8,16转化成⼆进制是10,100,1000,10000。

如果减1则变成01,011,0111,01111。

两者做按位与运算,结果如果为0,则X是2的N次⽅。

2、统计⼀个整数的⼆进制中1的个数int count_number_of_one(int number){ int counter = 0; while (number) { counter++; number &= number - 1 ; } return counter;}⼆、位运算基础很多⾼级的动态规划题⽬或者⼀些基础的运算往往需要较⾼的执⾏效率和较低的空间需求,或者需要表⽰⼀些状态集合,⽽位运算刚好能满⾜这⼀切。

很多的时候,恰当的位运算使⽤也能使程序变得更加简洁和优美。

1、位运算法则位运算是各位互不影响的,⽐如A为1010⽽B为1100,那么有A&B=1000A|B=1110A^B=0110~A=11110101 (1的个数是取决于A的类型的,这⾥认为A的类型是8位整型)另外两种位运算是位移运算a<<b,a>>b。

前者表⽰将a的所有位向左移动b位,后者则表⽰将a的所有位向右移动b位。

对于⾮负整数(往往这也是我们最关⼼的),新空出的位将会被0取代。

⽐如A为1001,⽽B为3,那么A>>B则为1。

⼤多数情况下可以简单地认为左移b位就是乘以2b,⽽右移b位则是除以(整除)2b。

当然这是存在例外的——对于负数是不能这么简单认为的:⽐如在GNU GCC/G++ 编译条件下,若A=-1,你会发现对于任何位移运算A<<B,⽆论B的取值如何,其结果均为-1。

因此请注意,在位移运算下务必确保对⾮负整数进⾏运算,以免发⽣不必要的问题。

对于位移运算最常⽤的操作就是取⼀个特定的位——⽐如1< xx>2、对于集合的表⽰⼤多数时候,我们可以⽤⼀个整数来表⽰⼀个包含不超过32(当然如果使⽤64位整型变量也可以是64个)个元素的集合——对于每⼀个位,如果元素为1,则表⽰存在当前位所对应的集合成员,如果是0,则表⽰这个集合成员是不存在的。

c语言判断位数

c语言判断位数

c语言判断位数1 什么是位数位数是计算机中一种重要的概念,它是对计算机存储单位大小的一种表示。

位数一般是以“比特”(Bit)计算的,一个比特可以表示为“0”或“1”,因此位数的大小决定了计算机可以储存多少数据。

比如,1位数表示的是只有2种可能--0或1,而8位数表示的则可以有256种可能--即0~255.2 如何利用C语言判断位数C语言拥有丰富的函数编程能力,可以帮助我们对数据进行各种有效的处理。

我们可以利用C语言的位运算函数来判断某个数的位数。

例如,位运算符(&)用于判断某个数是十六进制表示的十进制中的第几位;我们也可以使用C语言提供的关系运算符(比如“<”)来检查某个数所属的位数范围,比如,若我们所要求的位数范围是2位至4位之间,那么我们可以使用2种或3种关系运算符来检查:num > 1 && num < 16.3 C语言判断位数的优缺点C语言用来判断位数具有很多优点。

首先,C语言的语义本身就更加自由,因此程序员可以更充分地利用丰富的数据操作函数,根据不同的情况进行定制化的编程;另外,C语言也拥有一定量的容错能力,当程序出现运行错误时,程序员仍可以借助资源回收机制,实现程序的可重入调试。

然而,C语言也具有一定的缺点。

由于是低级语言,因此它相对更加复杂,要求程序员必须具备更高的编程技能和良好的抽象化思维能力,以便编写出更优雅的程序代码。

同时,由于C语言的不断发展,其语法变化迅速,易使程序员迷失,无法及时调整思维习惯。

总之,C语言是一种功能强大的低级语言,可以让程序员可以利用位运算函数等相关函数,有效地判断位数,并且可以满足不同的编程情况。

同时,C语言也有一定缺点,要求程序员必须熟悉语法、具备良好的编程思维,才能有效地编写程序。

C语言中的位运算技巧

C语言中的位运算技巧

C语言中的位运算技巧位运算是计算机中一种高效且常用的运算方式,它可以对数据进行处理、操作和压缩,广泛应用于各个领域。

在C语言中,位运算提供了一系列技巧,可以帮助程序员更好地处理数据。

本文将介绍一些常用的C语言中的位运算技巧。

一、位运算的基础知识在进行位运算之前,我们需要了解一些基础知识。

在C语言中,位运算符有以下几种:1. 与运算符(&):对两个操作数的每个位进行“与”运算,只有当两个操作数对应位都为1时,结果的对应位才为1。

2. 或运算符(|):对两个操作数的每个位进行“或”运算,只有当两个操作数对应位至少有一个为1时,结果的对应位才为1。

3. 异或运算符(^):对两个操作数的每个位进行“异或”(相同为0,不同为1)运算,只有当两个操作数对应位不同时,结果的对应位才为1。

4. 左移运算符(<<):将一个数的全部位向左移动若干位,左边超出的位将被丢弃,右边补0。

5. 右移运算符(>>):将一个数的全部位向右移动若干位,如果数是无符号的,则左边全部移入的位将被丢弃,右边补0;如果数是有符号的,则按照机器的规则决定。

二、位运算技巧1. 判断奇偶性我们可以通过位与运算符(&)来判断一个数的奇偶性。

假设有一个数x,如果x与1进行位与运算后的结果为0,则说明x为偶数;如果结果为1,则说明x为奇数。

2. 交换两个数我们可以通过异或运算符(^)来交换两个数的值,而无需使用临时变量。

假设有两个数a和b,我们可以通过以下方式进行交换:a = a ^ b;b = a ^ b;a = a ^ b;3. 判断一个数的二进制表示中有几个1我们可以通过循环位与运算符(&)和右移运算符(>>)来计算一个数的二进制表示中有多少个1。

假设有一个数x,我们可以通过以下方式计算1的个数:int count = 0;while(x != 0){if(x & 1){count++;}x = x >> 1;}4. 将某一位设置为1我们可以通过左移运算符(<<)和或运算符(|)来将某一位设置为1。

C语言中的位运算技巧

C语言中的位运算技巧

C语言中的位运算技巧位运算是C语言中一种十分重要且强大的运算方式,通过对二进制位的操作,可以实现许多高效而巧妙的计算。

本文将介绍一些常用的位运算技巧,以帮助大家更好地理解和应用C语言中的位运算操作。

一、与运算(&)与运算是位运算中最基本的一种运算,它的运算规则如下:如果两个相应的二进制位都为1,则该位的结果值为1,否则为0。

1. 判断奇偶性我们可以通过与运算来判断一个整数的奇偶性。

由于二进制数的最低位为1表示奇数,为0表示偶数,所以通过与1进行与运算即可得到结果:int num = 6;if (num & 1) {printf("奇数\n");} else {printf("偶数\n");}// 输出结果:偶数2. 清零指定位通过与运算,我们可以将一个指定位置0,而不影响其他位的值。

比如将二进制数1010的第二位变为0,可以进行以下操作: int num = 10; // 1010int mask = ~(1 << 1);num = num & mask;printf("%d\n", num);// 输出结果:8二、或运算(|)或运算的运算规则如下:如果两个相应的二进制位有一个为1,则该位的结果值为1,否则为0。

1. 将指定位设置为1通过或运算,我们可以将一个指定位置1,而不影响其他位的值。

比如将二进制数1010的第三位变为1,可以进行以下操作: int num = 10; // 1010num = num | (1 << 2);printf("%d\n", num);// 输出结果:142. 设置多个位通过或运算,我们还可以设置多个指定位置1,比如将第一位和第三位都设置为1,可以进行以下操作:int num = 10; // 1010num = num | (1 << 0) | (1 << 2);printf("%d\n", num);// 输出结果:11三、异或运算(^)异或运算的运算规则如下:如果两个相应的二进制位值不同,则该位的结果值为1,否则为0。

c语言16位数取位操作

c语言16位数取位操作

c语言16位数取位操作C语言中,可以使用位操作符对16位数进行位操作。

位操作可以在二进制位级别上对数值进行操作,包括位与(&)、位或(|)、位异或(^)、位取反(~)、左移(<<)和右移(>>)等操作。

1. 位与(&)操作:将两个数的对应位进行逻辑与操作,结果中的每个位都是两个数对应位上的逻辑与结果。

例如,对于两个16位数a和b,a & b的结果是一个新的16位数,其中每个位都是a和b对应位上的逻辑与结果。

2. 位或(|)操作:将两个数的对应位进行逻辑或操作,结果中的每个位都是两个数对应位上的逻辑或结果。

例如,对于两个16位数a和b,a | b的结果是一个新的16位数,其中每个位都是a和b对应位上的逻辑或结果。

3. 位异或(^)操作:将两个数的对应位进行逻辑异或操作,结果中的每个位都是两个数对应位上的逻辑异或结果。

例如,对于两个16位数a和b,a ^ b的结果是一个新的16位数,其中每个位都是a和b对应位上的逻辑异或结果。

4. 位取反(~)操作:对一个数的每个位进行逻辑取反操作,结果中的每个位都是原始数对应位上的逻辑取反结果。

例如,对于一个16位数a,~a的结果是一个新的16位数,其中每个位都是a对应位上的逻辑取反结果。

5. 左移(<<)操作:将一个数的所有位向左移动指定的位数,右侧空出的位用0填充。

例如,对于一个16位数a,a << n的结果是一个新的16位数,其中a的所有位都向左移动n位。

6. 右移(>>)操作:将一个数的所有位向右移动指定的位数,左侧空出的位用0填充。

例如,对于一个16位数a,a >> n的结果是一个新的16位数,其中a的所有位都向右移动n位。

这些位操作可以用于各种用途,例如对二进制数进行掩码操作、提取特定位、进行位级别的逻辑运算等。

在编写低级别的硬件相关代码或需要对二进制数据进行处理的应用程序中,位操作非常有用。

C语言中的位运算与位掩码技巧

C语言中的位运算与位掩码技巧

C语言中的位运算与位掩码技巧在C语言中,位运算与位掩码技巧是一种常用的技术,用来处理二进制数据和对内存进行精确的操作。

本文将介绍位运算的基本原理和位掩码技巧的应用,帮助你更好地理解和应用这些技术。

一、位运算的基本原理位运算是对二进制数据进行按位操作的技术,包括按位与(&)、按位或(|)、按位异或(^)、按位取反(~)等操作。

这些操作可以直接对整数的二进制表示进行处理,具有高效的特点。

下面分别介绍这些位运算操作的作用:1. 按位与(&):将两个操作数的对应位进行与运算,只有当两个位都为1时,结果位才为1,否则为0。

例如:1010 & 1100 = 1000。

2. 按位或(|):将两个操作数的对应位进行或运算,只要其中一个位为1,结果位就为1,否则为0。

例如:1010 | 1100 = 1110。

3. 按位异或(^):将两个操作数的对应位进行异或运算,只有当两个位不相同时,结果位才为1,否则为0。

例如:1010 ^ 1100 = 0110。

4. 按位取反(~):将操作数的每一位按位取反,即0变为1,1变为0。

例如:~1010 = 0101。

以上是位运算的基本原理,在实际编程中,我们可以结合位运算和位掩码技巧来实现各种复杂的操作。

二、位掩码技巧的应用位掩码技巧是利用位运算的性质来进行数据处理和内存操作的一种技术。

它通常以二进制形式的常量作为掩码,在操作中与某个值进行按位与运算,从而提取或者清除指定位的值。

以下是位掩码技巧的几个常见应用:1. 提取指定位的值:通过与一个掩码进行按位与运算,可以提取指定位的值。

假设有一个8位整数a,我们想要提取它的低4位的值,可以定义一个掩码0x0F,并与a进行按位与运算即可:value = a & 0x0F。

2. 清除指定位的值:通过与一个取反的掩码进行按位与运算,可以清除指定位的值。

假设有一个8位整数a,我们想要清除它的高4位的值,可以定义一个掩码0xF0,并与a进行按位与运算即可:value = a & 0xF0。

C语言中的位运算位操作和位掩码技巧

C语言中的位运算位操作和位掩码技巧

C语言中的位运算位操作和位掩码技巧C语言中的位运算和位掩码技巧位运算和位掩码技巧是C语言中常用的编程技巧,可以在处理二进制数据时提供高效的解决方案。

本文将介绍C语言中常见的位运算操作和位掩码技巧,并提供相关示例。

一、位运算操作位运算操作是直接操作二进制数的运算,包括按位与(&)、按位或(|)、按位异或(^)和按位取反(~)等。

这些操作可以方便地在二进制数据中提取、设置或者修改指定位的值。

1. 按位与(&):将两个操作数的对应位相与,结果为1的位表示原始两个操作数在该位置上都为1,否则为0。

示例:```cunsigned int num1 = 25; // 二进制表示为00011001unsigned int num2 = 14; // 二进制表示为00001110unsigned int result = num1 & num2; // 结果为00001000,十进制为8 ```2. 按位或(|):将两个操作数的对应位相或,结果为1的位表示原始两个操作数在该位置上至少有一个为1。

示例:```cunsigned int num1 = 25; // 二进制表示为00011001unsigned int num2 = 14; // 二进制表示为00001110unsigned int result = num1 | num2; // 结果为00011111,十进制为31 ```3. 按位异或(^):将两个操作数的对应位进行异或,结果为1的位表示原始两个操作数在该位置上不同。

示例:```cunsigned int num1 = 25; // 二进制表示为00011001unsigned int num2 = 14; // 二进制表示为00001110unsigned int result = num1 ^ num2; // 结果为00010111,十进制为23 ```4. 按位取反(~):对操作数进行逐位取反,即0变为1,1变为0。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

巧妙运用C语言位运算
位运算
位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。

位运算符有:
&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。

其中,按位取反运算符是单目运算符,其余均为双目运算符。

位运算符的优先级从高到低,依次为~、&、^、|,
其中~的结合方向自右至左,且优先级高于算术运算符,其余运算符的结合方向都是自左至右,且优先级低于关系运算符。

(1)按位与运算符(&)
按位与运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。

即同为 1 的位,结果为1,否则结果为0。

例如,设3的内部表示为
00000011
5的内部表示为
00000101
则3&5的结果为
00000001
按位与运算有两种典型用法,一是取一个位串信息的某几位,如以下代码截取x的最低7位:x & 0177。

二是让某变量保留某几位,其余位置0,如以下代码让x只保留最低6位:x = x & 077。

以上用法都先要设计好一个常数,该常数只有需要的位是1,不需要的位是0。

用它与指定的位串信息按位与。

(2)按位或运算符(|)
按位或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1
即只要有1个是1的位,结果为1,否则为0。

例如,023 | 035 结果为037。

按位或运算的典型用法是将一个位串信息的某几位置成1。

如将要获得最右4为1,其他位与变量j的其他位相同,可用逻辑或运算017|j。

若要把这结果赋给变量j,可写成:j = 017|j
(3)按位异或运算符(^)
按位异或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相应位的值相同的,结果为0,不相同的结果为1。

例如,013^035结果为026。

异或运算的意思是求两个运算分量相应位值是否相异,相异的为1,相同的为0。

按位异或运算的典型用法是求一个位串信息的某几位信息的反。

如欲求整型变量j 的最右4位信息的反,用逻辑异或运算017^j,就能求得j最右4位的信息的反,即原来为1的位,结果是0,原来为0的位,结果是1。

(4)按位取反运算符(~)
按位取反运算是单目运算,用来求一个位串信息按位的反,即哪些为0的位,结果是1,而
哪些为1的位,结果是0。

例如, ~7的结果为0xfff8。

取反运算常用来生成与系统实现无关的常数。

如要将变量x最低6位置成0,其余位不变,可用代码x = x & ~077实现。

以上代码与整数x用2个字节还是用4个字节实现无关。

当两个长度不同的数据进行位运算时(例如long型数据与int型数据),将两个运算分量的右端对齐进行位运算。

如果短的数为正数,高位用0补满;如果短的数为负数,高位用1补满。

如果短的为无符号整数,则高位总是用0补满。

位运算用来对位串信息进行运算,得到位串信息结果。

如以下代码能取下整型变量k的位串信息的最右边为1的信息位:((k-1)^k) & k。

移位运算
移位运算用来将整型或字符型数据作为二进位信息串作整体移动。

有两个运算符:
<< (左移) 和>> (右移)
移位运算是双目运算,有两个运算分量,左分量为移位数据对象,右分量的值为移位位数。

移位运算将左运算分量视作由二进位组成的位串信息,对其作向左或向右移位,得到新的位串信息。

移位运算符的优先级低于算术运算符,高于关系运算符,它们的结合方向是自左至右。

(1)左移运算符(<<)
左移运算将一个位串信息向左移指定的位,右端空出的位用0补充。

例如014<<2,结果为060,即48。

左移时,空出的右端用0补充,左端移出的位的信息就被丢弃。

在二进制数运算中,在信息没有因移动而丢失的情况下,每左移1位相当于乘2。

如4 << 2,结果为16。

(2)右移运算符(>>)
右移运算将一个位串信息向右移指定的位,右端移出的位的信息被丢弃。

例如12>>2,结果为3。

与左移相反,对于小整数,每右移1位,相当于除以2。

在右移时,需要注意符号位问题。

对无符号数据,右移时,左端空出的位用0补充。

对于带符号的数据,如果移位前符号位为0(正数),则左端也是用0 补充;如果移位前符号位为1(负数),则左端用0或用1补充,取决于计算机系统。

对于负数右移,称用0 补充的系统为“逻辑右移”,用1补充的系统为“算术右移”。

以下代码能说明读者上机的系统所采用的右移方法:
printf("%d\n\n\n", -2>>4);
若输出结果为-1,是采用算术右移;输出结果为一个大整数,则为逻辑右移。

移位运算与位运算结合能实现许多与位串运算有关的复杂计算。

设变量的位自右至左顺序编号,自0位至15位,有关指定位的表达式是不超过15的正整数。

以下各代码分别有它们右边注释所示的意义:
~(~0 << n)/* 实现最低n位为1,其余位为0的位串信息*/
(x >> (1+p-n)) & ~(~0 << n) /* 截取变量x自p位开始的右边n位的信息*/ new |= ((old >> row) & 1) << (15 – k) /* 截取old变量第row位,并将该位信息装配到变量new的第15-k位*/
s &= ~(1 << j) /* 将变量s的第j位置成0,其余位不变*/
for(j = 0; ((1 << j) & s) == 0; j++) ; /* 设s不等于全0,代码寻找最右边为1的位的序号j */
!为逻辑取反,表示非的意思,经过它处理后的结果为布尔型,要么为0,要么为1,!x,只要x不为0,1,2,3,都可以,那么!x的结果就是0,只有当x为0时,结果为1。

如果*为真,则!*为假,反之如果*为假,则!*为真
一个硬件工程师的故事。

相关文档
最新文档