位运算

位运算都是对操作数在内存中的二进制位进行操作
注意:只能操作整数类型,不能操作浮点数!
因为整数在内存中表示的是自己本身的值,而浮点数却不是(IEEE745)
这种限是编译器限制的,因为对以浮点表示法的浮点数进行位运算没有数学意义

搜罗一番,只找到其一个用途,从硬件上快速支持浮点数fabs,就是数学中的绝对值。不过从语言层面,从我知道的语言当中,都是禁止

这里有办法

位运算操作符

C语言提供了六种位运算符:

按位与(&)

只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0

	1010
&	0110
-----------
	0010
10 & 6 = 2

按位或(|)

参与|运算的两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0

	1010
|	0110
-----------
	1110
10 | 6 = 14

按位异或(^)

参与^运算两个二进制位不同时,结果为 1,相同时结果为 0

	1010
^	0110
-----------
	1100
10 ^ 6 = 12

按位取反(~)

取反运算符~为单目运算符,右结合性,作用是对参与运算的二进制位取反

~	1010
----------	
	0101
~a = -(a+1) //

左移运算(<<)

左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补0

<<2 10110111
-------------
  101110111
  
6 = 0110
6 << 1 = 1100 = 12
6 << 2 = 1000 = 24

左移n位就是将数乘以2的n次方

右移运算(>>)

右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1

>>2 10110111
---------------
      10110111
6 = 0110
6 >> 1 = 0011 = 3
6 >> 2 = 0001 = 1

右移n位就是将数除以2的n次方


& | ^ 满足交换律和结合律

用法

将最右侧的1翻转成0

x&(x-1)

x:			01110100
x-1:		01110011
x&(x-1):     01110000

将最右侧连续o串转化为1

x|(x-1)

x:			00101000
x-1:		00100111
x|(x-1):     00101111

将最右侧连续1串转化为0

((x|(x-1))+1)&x

x:					00101100
x-1:				00101011
((x|(x-1))+1)&x:      00100000
posted @ 2023-08-27 23:34  -37-  阅读(22)  评论(0编辑  收藏  举报