首页 > 其他分享 >位运算符

位运算符

时间:2022-10-11 16:01:49浏览次数:45  
标签:xor 运算 二进制 末位 运算符 swap shl

最近用的很多,快快熟悉。



=== 1. and运算 ===



and运算通常用于二进制取
​​位操作​​​,例如一个数 and 1的结果就是取
​​​二进制​​​的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为
​​​偶数​​,最末位为1表示该数为奇数。



相同位的两个数字都为1,则为1;若有一个不为1,则为0。



00101



11100



(&;或者and)



----------------



00100



=== 2. or运算 ===



or运算通常用于二进制特定位上的无条件
​​赋值​​,例如一个数or 1的结果就是把二进制最末位强行变成1。如果需要把二进制最末位变成0,对这个数or 1之后再减一就可以了,其实际意义就是把这个数强行变成最接近的偶数。



相同位只要一个为1即为1。



00101



11100



(|或者or)



----------------



11101



=== 3. xor运算 ===



异或的符号是^。按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0.



xor运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a xor b) xor b = a。xor运算可以用于简单的加密,比如我想对我MM说1314520,但怕别人知道,于是双方约定拿我的生日19880516作为
​​密钥​​。1314520 xor 19880516 = 20665500,我就把20665500告诉MM。MM再次计算20665500 xor 19880516的值,得到1314520,于是她就明白了我的企图。



相同位不同则为1,相同则为0。



00101



11100



(^或者xor)



----------------



11001



运算结果



x <- x # y



y <- x @ y



x <- x @ y



执行了第一句后x变成了x # y。那么第二句实质就是y <- x # y @ y,由于#和@互为逆运算,那么此时的y变成了原来的x。第三句中x实际上被赋值为(x # y) @ x,如果#运算具有交换律,那么赋值后x就变成最初的y了。这三句话的结果是,x和y的位置互换了。



加法和减法互为逆运算,并且加法满足交换律。把#换成+,把@换成-,我们可以写出一个不需要临时
​​变量​​的swap过程(Pascal)。



procedure swap(var a,b:longint);



begin



a:=a + b;



b:=a - b;



a:=a - b;



end;



好了,刚才不是说xor的逆运算是它本身吗?于是我们就有了一个看起来非常诡异的swap过程:



procedure swap(var a,b:longint);



begin



a:=a xor b;



b:=a xor b;



a:=a xor b;



end;



注意:位运算版本的交换两数不适用于一个数的自我交换。也就是说,如果上述程序的“b”改成“a”的话,其结果是
​​变量​​a变成零。因此,在使用快速排序时,由于涉及到一个数的自我交换,因此如果要在其中使用位运算版的交换两数的话,应该先判断。具体的时间损耗在此略过。



=== 4. not运算 ===



not运算的定义是把内存中的0和1全部取反。使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是
​​无符号整数​​​(不能表示负数),那么得到的值就是它与该类型
​​​上界​​的差,因为无符号类型的数是用00到$FFFF依次表示的。下面的两个程序(仅语言不同)均返回65435。



var



a:word;



begin



a:=100;



a:=not a;



writeln(a);



end.


1


2


3


4


5


6


7


8

​​#include<stdio.h>​​


​​int​​ ​​main()​​


​​{​​


​​unsigned ​​ ​​short​​ ​​a=100;​​


​​a=~a;​​


​​printf​​ ​​(​​ ​​"%d\n"​​ ​​,a);​​


​​return​​ ​​0;​​


​​}​​



如果not的对象是有符号的整数,情况就不一样了,稍后我们会在“整数类型的储存”小节中提到。



=== 5. shl运算 ===



a shl b就表示把a转为二进制后左移b位(在后面添b个0)。例如100的二进制为1100100,而110010000转成十进制是400,那么100 shl 2 = 400。可以看出,a shl b的值实际上就是a乘以2的b次方,因为在二进制数后添一个0就相当于该数乘以2。



通常认为a shl 1比a * 2更快,因为前者是更底层一些的操作。因此程序中乘以2的操作请尽量用左移一位来代替。



定义一些
​​常量​​​可能会用到shl运算。你可以方便地用1 shl 16 - 1来表示65535。很多算法和
​​​数据结构​​​要求数据规模必须是2的幂,此时可以用shl来定义Max_N等
​​​常量​​。



=== 6. shr运算 ===



和shl相似,a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。我们也经常用shr 1来代替div 2,比如
​​二分查找​​、堆的插入操作等等。想办法用shr代替除法运算可以使程序效率大大提高。最大公约数的二进制算法用除以2操作来代替慢得出奇的mod运算,效率可以提高60%。


C语言中位运算符之间,按优先级顺序排列为



1

~

2

<<、>>

3

&

4

^

5

|

6

&=、^=、|=、<<=、>>=


标签:xor,运算,二进制,末位,运算符,swap,shl
From: https://blog.51cto.com/u_12911014/5746516

相关文章

  • Java学习之路:运算符
    2022-10-1010:34:08......
  • Java运算符
    Java运算符逻辑运算符与&&,或||,非!逻辑与运算:两个结果都为真,结果才为true,如果前面代码判断为错,后面则不执行。逻辑或运算:两个变量有一个为真,则结果才为true。逻辑......
  • 优先级排序为:算术运算符 > 关系运算符 > 赋值运算。
    优先级排序为:算术运算符>关系运算符>赋值运算。算术运算符中,-负数(如–1)、%百分比、^乘方、*和/(乘和除)、+和–(加和减)属于优先级第三级,加法运算符【+】、减法......
  • 多层三目运算符
    参考:https://blog.csdn.net/qq_36138652/article/details/115789463......
  • 运算符
    java中支持的运算符算数运算符+,-,*,/,%,++,--+,左右任意一侧存在字符串,那么一定进行字符串拼接++,在单独使用的时候,不困放在前后,都是加1的操作++......
  • C++运算符
    目录 ​​算术运算符(进行四则运算)​​​​赋值运算符(表达式的值赋给变量)​​​​比较运算符(表达是比较,返回一个真值或假值)​​​​逻辑运算符(返回表格式的结果真或......
  • java---了解以下运算符
    了解即可1&2用于条件判断,&条件1和2都执行1&&2,条件1判断错误的情况下,条件2不执行&当运算符的化,例如4&7,两者上下对比都是1则为1,反之为0,结果就是二进制100也就是......
  • 布尔类型、比较运算符
    布尔类型True表示真(是、肯定)False表示假(否、否定)变量名称=布尔类型字面量比较运算符代码案例#定义变量存储布尔类型的数据bool_1=Truebool_2......
  • 运算符
    运算符(自增自减)Java语言支持的运算符算数运算符:+-*/%++--赋值运算符=关系运算符><<=>===!=instanceof逻辑运算符&&||!位运算符......
  • 第二章:数据类型、运算符和表达式
    目录​​一、在屏幕上输出英文短句“Programmingisfun.”。​​​​ 二、输入半径,分别计算球体积和球表面积。​​​​ 三、转义字符使用示例。​​​​ 四:利用符号常......