×

位运算

位运算常见用法?【总结】位运算常见技巧

admin admin 发表于2024-09-22 00:58:24 浏览1 评论0

抢沙发发表评论

本篇文章给大家谈谈位运算,以及位运算常见用法对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

本文目录

位运算常见用法

参加运算的两个数据,按二进制位进行“与”运算。 运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0 例如:3&5 即 0000 0011& 0000 0101 = 00000001 因此,3&5的值得1。 另,负数按补码形式参加按位与运算。 “与运算”的特殊用途: 方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。 参加运算的两个对象,按二进制位进行“或”运算。 运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1; 即 :参加运算的两个对象只要有一个为1,其值为1。 例如:3|5 即 00000011 | 0000 0101 = 00000111 因此,3|5的值得7。 另,负数按补码形式参加按位或运算。 “或运算”特殊作用: (1)常用来对一个数据的某些位置1。 方法:找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1。 例:将X=10100000的低4位置1 ,用X | 0000 1111 = 1010 1111即可得到。 参加运算的两个数据,按二进制位进行“异或”运算。 运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0; 即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。 “异或运算”的特殊作用: (1)使特定位翻转找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。 例:X=10101110,使X低4位翻转,用X ^0000 1111 = 1010 0001即可得到。 (2)与0相异或,保留原值 ,X ^ 00000000 = 1010 1110。 下面重点说一下按位异或,异或其实就是不进位加法,如1+1=0,,0+0=0,1+0=1。 异或的几条性质: 1、交换律 2、结合律(即(a b) c == a (b c)) 3、对于任何数x,都有x x=0,x 0=x 4、自反性: a b b=a^0=a; 异或运算最常见于多项式除法,不过它最重要的性质还是自反性:A XOR B XOR B = A,即对给定的数A,用同样的运算因子(B)作两次异或运算后仍得到A本身。这是一个神奇的性质,利用这个性质,可以获得许多有趣的应用。 例如,所有的程序教科书都会向初学者指出,要交换两个变量的值,必须要引入一个中间变量。但如果使用异或,就可以节约一个变量的存储空间: 设有A,B两个变量,存储的值分别为a,b,则以下三行表达式将互换他们的值 表达式 (值) : a=a^b; b=b^a; a=a^b; 1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现 一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空 间,能否设计一个算法实现? 解法一、显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+...+1000的和。 这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。 解法二、异或就没有这个问题,并且性能更好。 将所有的数全部异或,得到的结果与1 2 3 ... 1000的结果进行异或,得到的结果就是重复数。***隐藏网址*** 一系列数中,除两个数外其他数字都出现过两次,求这两个数字,并且按照从小到大的顺序输出.例如 2 2 1 1 3 4.最后输出的就是3 和4 这个题就是首先在输入的时候一直异或,就可以把这两个数异或的乘积找出来,就比如上例中x=3^4; 然后找一个变量tmp来分开这两个数.按位与的话可以发现会分开这两个数分别存在num1和num2中.然后就有结果了. 将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。 例:a = a《《 2将a的二进制位左移2位,右补0, 左移1位后a = a *2; 若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。 将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。 操作数每右移一位,相当于该数除以2。 例如:a = a》》 2 将a的二进制位右移2位, 左补0 or 补1得看被移数是正还是负。 位运算符与赋值运算符结合,组成新的复合赋值运算符,它们是: 运算规则:和前面讲的复合赋值运算符的运算规则相似。 不同长度的数据进行位运算 如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,然后进行位运算。 以“与”运算为例说明如下:我们知道在C语言中long型占4个字节,int型占2个字节,如果一个long型数据与一个int型数据进行“与”运算,右端对齐后,左边不足的位依下面三种情况补足, (1)如果整型数据为正数,左边补16个0。 (2)如果整型数据为负数,左边补16个1。 (3)如果整形数据为无符号数,左边也补16个0。 如:long a=123;int b=1;计算a& b。 如:long a=123;int b=-1;计算a& b。 如:long a=123;unsigned intb=1;计算a & b。

【总结】位运算常见技巧

***隐藏网址***

根据数的二进制表示可知,除了最低位的 0 或者 1,其余位都是 0*2^n 或者 1*2^n,必为偶数,偶数 + 偶数 = 偶数,所以决定一个数是否为偶数的关键条件就是二进制最低位是 0 还是 1,如果是 0,则为偶数,否则为奇数(偶数 + 奇数 = 奇数)。此时问题被转化为判断数的二进制表示中,判断最低位是 0 还是 1,这时通过按位与 0x1,过滤掉除去最低位的其他位信息,输出的结果与 0 比较即可判断奇偶性

根据数的二进制与十进制的转化规则可知,每一位 bit 乘以 2 的幂次位数和即为十进制表达式,如果一个数为 2 的整数次幂,则此数的二进制中,只能由一位是1,其余位都为0(如果有多个1,则幂次不为整数),所以问题进一步转化为判断一个数的二进制表示中,是否只有一位是 1。这里还需要利用一个性质,即 x & (x - 1) == 0 的充要条件是 x 二进制表达式中只有1个位1 ,例如 0x00100 & 0x00011 = 0 , 0x00101 & 0x00100 != 0

考虑前一个问题:“判断数是否为 2 的整数次幂”,是否可以理解为:“判断数二进制表达中位1的个数是否为1个”,解决方法是通过 num & (num - 1) == 0 。那么如何确认二进制表达中是否拥有两个位1呢,我们观察: 0x00101 & 0x00100 = 0x00100 ,再进行一次 0x00100 & 0x00011 = 0 ,我们发现只需要将 num & (num - 1) 进行两次,最后等于0即可。解决也是如此,每进行一次 num & (num - 1) ,都会让最低的那个位1被消除。只需要循环进行操作,记录下次数即可

使用位运算进行处理的前提需要了解并运用一下的异或结论:

同时需要知道,异或满足交换律和结合律: A ^ C ^ A ^ C ^ B == (A^A) ^ (C^C) ^ B

综上: A ^ C ^ A ^ C ^ B = (A^A) ^ (C^C) ^ B = 0 ^ 0 ^ B = B

此题只需要依次对数组的数进行异或,相同的数异或为0,最后的结果则为只出现过一次的值

求位运算 详解

位运算就是把操作数转换成二进制形式,相对应的位进行运算有不同的位运算符:&与,1&1为1 其余情况为0|或,0|0为0 其余情况为1^异或,相同为0,相反为1~取反,0变为1 1变为0》》右移《《左移_RGB32BIT(a,r,g,b) ( (b) + ((g) 《《 8) + ((r) 《《 16) + ((a) 《《 24) )a向左移动24位,也就是3个字节r向左移动16位,也就是2个字节g向左移动8位,也就是1个字节b不移动四者相加,从低到高4个字节为:b g r a

关于位运算

∧、∨是数学(例如数理逻辑)中的二元逻辑运算符。前者是合取(逻辑与)运算,当且仅当两个运算数都为真时结果为真;后者是析取(逻辑或)运算,当且仅当两个运算数都为假时结果为假。在类C语言中,∧对应&&,∨对应||。当运算数只取0或1(或者表示为字面量false或true,有些语言如Java不允许隐式到整数0或1的转换)时,&&等价于位操作符&,||等价于位操作符|。在BASIC和其它一些语言中,∧对应AND,∨对应OR。与类C语言规定不同的是,∧和∨的优先级不是一定的。有些作者把∧和∨当作相同优先级的运算符;另外一些作者把∧置于比∨更高的优先级(对应有&&优先级高于||)。至于类C语言中的位操作符^,对应于数学中的逻辑异或运算(当且仅当两个运算数真值不同时结果为真),和这里的∧印刷出来应该有明显的区别。====

位运算的运算规则是什么

首先,^是异或,不是或,异或是指位不同则为1。

-3^2:-0011 ^ 0010(以四位为例,实际一般是32位,和机器有关) 负数要用补码(除符号位外取反加1)计算,即 1011 取反加1 : 1101(-3补码), 1101 ^ 0010得 1111(补码),转原码,减1取反,即1110再取反,1001所以结果为 -1;

而 3^-2,实际上是 0011^1110(-2,1010的补码) ,得1101(结果补码),减1取反,得1011(原码),-3;

-3^-2,即 1101^1110,得0011,即3,而 3^2,即0011^0010,得,0001,即1;

~表示取反,3为0011,~3就是1100,2为0010,~2就是1101, ~3^~2,即 1100^1101,得0001,即1。

扩展资料:

位运算就是二进制数值按照位运算符&(与),|(或),~(取反),^(异或),》》(左移),《《(右移)对二进制数值进行运算,我们知道 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。

比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。

C语言中的位运算是怎样的

C语言是为描述系统而设计的,它的第一个应用就是UNIX操作系统的设计,因此必须具有低级语言的特点。指针运算和位运算就是其代表。我们知道,计算机中的信息以及控制信号均是以二进制码的0、1的形式存储和处理的。每一个0或1称为一个“位”(bit),8位构成一个字节(byte)。在内存中,每一个字节均有一个编号,称为内存地址。在以前的各章节中,我们都是将一个字节(如字符型)和若干字节(如整型、实型等)中的内容作为一个整体进行处理的(赋值、运算、I/O操作)。位运算则是针对这些字节中的若干位进行操作。这在系统软件设计中和自动控制中是十分有用的。C语言的位运算符有~,《《,》》,&,|,^共6个,并可与赋值运算符相结合(除~外)成为位运算赋值操作。应注意:参与位运算的量只能是整型和字符型。

C语言 位运算

###位运算的逻辑: 1:(位与)运算符(&):双目操作符,当两个位进行相与时,只有两者都为“1”时结果才为“1”(即:全真为真,一假为假),运算规则如下: 左运算量                        右运算量                        &运算结果     0                    &                0                     =                    0     0                    &                 1                    =                    0     1                    &                  0                   =                     0     1                    &                   1                  =                     1 运算: 例: #include  《stdio.h》 int main(int     argc,char    *crgv){     unsigned            char    x=0156,    y=0xaf,   z; z=x&y printf("%d",z) } 结果为:0x2e 运算过程:0156(8进制)==0000 0110 1110(2进制); 进行                                          &(位与运算)                     0xaf(16进制)     ==0000 1010    1111(2进制); 结果:0000    0010    1110(2进制)==0x2e(十六进制);2:位或运算符(|): 双目操作符,当两个 位  进行相或时,两者中只要有一方为“1”,结果就为“1”(即:一真为真,两假为假),运算规则如下:     左运算量                            右运算量                           (|) 运算结果             0                    |                     0                        =                            0             1                    |                    1                        =                            1             0                    |                    1                    =                                1             1                    |                     1                    =                               1 例: #include 《stdio.h》 int main(int argv,char  *argc){ unsigned char x=027,y=0x75; z=x|y; } 运行过程: 027(8进制)=0001   0111(2进制) 进行                    |(位或运算) 0x75(16进制)=0111    0101(2进制) 结果:0111   0111(2进制)=0x77(16进制)3.异或运算(^):     当两个位进行异或时,只要两者相同,结果为“0”,否者结果为“1”,(即:同假异真)运算规则如下: 左运算量                            右运算量                           (^) 运算结果             0                    ^                    0                        =                            0             1                    ^                    1                         =                            0             0                    ^                    1                          =                            1             1                    ^                    0                          =                             1 例: #include int main(int argv,char  *argc){ unsigned(无符号)     char    x=25,y=0263,z; z=x^y; printf("%d\n",z); } 运算过程: 25(十进制)=0001    1001(二进制) 运算                    ^(异或运算) 0263(8进制)=1011    0011(二进制) 结果:1010     1010(二进制)=0252(8进制)4:移位操作符(“《《”   或   "》》"):位移位运算的一般形式:《运算量》《运算符》《表达式》; 《运算量》必须为整型结果数值: 《运算符》为左移位(《《)或 右移位(》》)运算; 《表达式》也必须为整型结果数值; 移位操作就是把一个数值左移或右移若干位;假如左移n位,原来值最左边的n位数被丢掉,右边n卫补“0” ;右移操作就是和左移操作移动方向相反; 符号位的处理方法: (1):逻辑移位,不考虑符号问题,原数值右移n位后,左边空出的n歌位置,用0填充; (2):算术移位,原来值进行了右移操作后,需要保证符号位不变,因此,右移n位后,左边空出的n个位置,用原数值的符号位填充。原来若是负数,则符号位为“1”,填充的位也是“1”;原来若是正数,则符号位为“0”,填充的位也是“0”,这样保证移位后的数据与原数正负相同; 例:“1000   1001”将其右移两位,逻辑移位的结果为“0010  0010”,算术移位为:“1110  0010”; 将其左移两位,逻辑移位和算术移位的结果为:“0010  0100”; (3)***补充:特定位清零(由“1”变成“0”)用 位与  操作;特定位变“1”(由“0”变成“1”)用  位或操作; 例: a、请把0xd5的第2位进行清零操作 0xd5=1101 0101=》1101 0001     1111 1011     ~0000 0100     =0000 0001《《2   ~(0x01《《2)&0xd5 b、请把0xed的第3位进行清零操作 0xed=1110 1101=》1110 0101     1111 0111     ~     0000 1000 =    0000 0001《《3     ~(0x01《《3)&0xed c、请把0x7d的第2-4位进行清零 0x7d=0111 1101=》0110 0001     1110 0011     ~     0001 1100 =     0000 0111《《2 ~(0x07)&0x7d d、请把0x7d的第2位和第3位进行清零 0x7d=0111 1101=》0111 0001     1111 0011 ~     0000 1100     0000 0011《《2 ~(0x03《《2)&0x7d e、请把0xc7的第4位进行置1 0xc7=1100 0111=》1101 0111     0001 0000     =0000 0001《《4 =~(0x01《《4)|0xc7 f、请把0x87的第3位进行置1  0x87=1000 0111=》1000 1111     0000 1000 ~(0x01《《3)|0x87 g、请把0xc7的第3—5位置1 0xc7=1100 0111=》1111 1111     0011 1000     0000 0111《《3 ~(0x07《《3)|0x87

php 的位运算总结

php的位运算很少会用到,但是用处很大, 在有些算法中会用到,在权限管理中也会经常用到, 对于理解计算机的世界也会有一定的帮助,所以得把这些重要但不常用的东西总结一下记录一下。

提到位运算,避不开的是二进制。

因为位运算是直接在内存做操作和运算,相较与直接拿两个变量做运算符肯定是更快的。

很多地方把二进制这玩意说得很晦涩,现在来以最简单的方式来总结一下,当然只算 int 范围内的数算了,超过了这个范畴程序员还不如拿这时间去学点别的。

说完以上总结,再来解释下什么是二进制,网上大把, 但只要记住,int范围内的数也就是我们大部分需要用到的数,都可以用二进制来表示。

我们生活中用到的计数方式为十进制,由个数位满10进1, 然后再开始重新计算,等十位满9再加一时,百位加一,十位归零。

二进制则只有两个数字来表示就是0和1,满2进1。 由32个位组成,虽然只有32个位但已满足了我们正常的需求了

比如说1转换为2进制原码,由于1是正数所以符号位为0, 原码反码补码都一个样。 1的原码:00000000 00000000 00000000 00000001 因手懒,太多0太丑用+拼接,’0* 8’代表8个0

2的原码:0* 8 0* 8 0* 8 0* 6 + 1 0,既然是二进制, 满2就得进1,最低位归0,向前加一。 再来解释下负数的原码反码和补码,就开始讲php的位运算了。

二进制复习完毕。下面开始讲讲php的位运算。

php一共有六种位运算,一种一种来讲。

可以这么理解,两个数的补码放在一起比较每个位(一共32个位), 可以得出另外一个数,这个数字的组成由比较的两位数字生成, 如果两个数的每个位数上的数字都等于1的话, 那得到的那个数的补码的同位为1,否则为0。 听着绕口,其实很简单,觉得还是比官网上的更容易让新手看懂 下面举例子:

首先来求-1和7的补码。7的原码就是补码。

两个补码都有了下面开始运算:

按照上面的说法, 每个位都有一样则 $a 的同等位则为1,刚好-1的补码和7的补码前面都不一样,就最后三位一样,所以刚好求得的 $a 的补码的最后三位是1而其他的都是0 ,刚好这个补码为正数,正好就是7。

其实就是和按位与相反,只要有1个为1,那就为1,如果都不为1,那就为0。

$a = -1|7 ;得出来的 $a 补码为32个1,但此时不能说 $a 就是-1,因为这只是补码,要转成原码再转成十进制数,补码-1,然后再翻转,再转出来,得到的其实也还是-1。

就是将这个数的补码全部翻转过来,包括符号位,0变1,1变0 取反的结果一定是整数变负数负数变正数,取正数的反时, 记得一定要从补码一步步转到原码再转成十进制数才是答案。

两个数的补码比较,同等位上的两数比较 ,不一样时,则答案的补码的同位则为1,否则为0。

往左移符号位被挤走右边0补充,往右移动,符号位不动, 高位以符号位补充。二进制世界里往左移动其实是相当于乘以了2, 右移相当于除以了2。

不吹牛逼的说,这应该是互联网上最容易理解的php位运算的解释和二进制的解释了。

原文链接: php的位运算总结-PHP

Python语法小记忆

Python 中的字符串还支持转义字符。所谓转义字符是指使用反斜杠“\”对一些特殊字符进行转义。 转义字符说明 \ 续行符 \n 换行符 \0 空 \t 水平制表符,用于横向跳到下一制表位 \’’ 双引号 \’ 单引号 \\ 一个反斜杠 \f 换页 \0dd 八进制数,dd 代表字符,如\012 代表换行 \xhh 十六进制数,hh 代表字符,如\x0a 代表换行 在Python 中,提供了如下表所示的函数进行数据类型的转换。 函数作用 int(x) 将x 转换成整数类型 float(x) 将x 转换成浮点数类型 complex(real ) 创建一个复数 str(x) 将x 转换为字符串 repr(x) 将x 转换为表达式字符串 eval(str) 计算在字符串中的有效Python 表达式,并返回一个对象 chr(x) 将整数x 转换为一个字符 ord(x) 将一个字符x 转换为它对应的整数值 hex(x) 将一个整数x 转换为一个十六进制字符串 oct(x) 将一个整数x 转换为一个八进制的字符串 赋值运算符主要用来为变量等赋值。使用时,可以直接把基本赋值运算符“=”右边的值赋给左边的变量,也可以进行某些运算后再赋值给左边的变量。在Python 中常用的赋值。 运算符如下表所示。 运算符说明举例展开形式 = 简单的赋值运算x=y x=y += 加赋值x+=y x=x+y -= 减赋值x-=y x=x-y *= 乘赋值x*=y x=x*y /= 除赋值x/=y x=x/y %= 取余数赋值x%=y x=x%y **= 幂赋值x**=y x=x**y //= 取整除赋值x//=y x=x//y 比较运算符,也称关系运算符,用于对变量或表达式的结果进行大小、真假等比较,如果比较结果为真,则返回True,如果为假,则返回False。比较运算符通常用在条件语句中作为判断的依据。Python 中的比较运算符如下表所示。 运算符作用举例结果 》 大于’a’ 》 ’b’ False 《 小于156 《 456 True == 等于’c’ == ’c’ True != 不等于’y’ != ’t’ True 》= 大于或等于479 》= 426 True 《= 小于或等于62.45 《= 45.5 False 逻辑运算符是对真和假两种布尔值进行运算,运算后的结果仍是一个布尔值,Python中的逻辑运算符主要包括and(逻辑与)、or(逻辑或)、not(逻辑非)。 运算符含义用法结合方向 and 逻辑与op1 and op2 从左到右 or 逻辑或op1 or op2 从左到右 not 逻辑非not op 从右到左 所谓运算符的优先级,是指在应用中哪一个运算符先计算,哪一个后计算,与数学的四则运算应遵循的“先乘除,后加减”是一个道理。 下表按从高到低的顺序列出了运算符的优先级。同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。 运算符说明 ** 幂 ~、+、- 取反、正号和负号 *、/、%、// 算术运算符 +、- 算术运算符 《《、》》 位运算符中的左移和右移 & 位运算符中的位与 ^ 位运算符中的位异或 | 位运算符中的位或 《、《=、》、》=、!=、== 比较运算符 在Python 中,使用内置函数input()可以接收用户的键盘输入。input()函数的基本用法如下: variable = input("提示文字") 其中,variable 为保存输入结果的变量,双引号内的文字用于提示要输入的内容。 默认的情况下,在Python中,使用内置的print()函数可以将结果输出到IDLE或者标准控制台上。其基本语法格式如下: Print(输出内容) 其中,输出内容可以是数字和字符串(字符串需要使用引号括起来),此类内容将直接 输出,也可以是包含运算符的表达式,此类内容将计算结果输出。

请问下,JAVA里,做除以1000的运算,用移位算法,怎么写,举例吧:a>>2就是a除以4的写法

不可以用移位算法做除以1000的操作,因为移位算法主要是二进制数据的操作!所以移位的数据单位只能是1、2、4、8、16、32、64、128、256、512、1024....等等。而且移位算法只能得到整数值,没有余数。所以建议不要考虑此方法,而且加减乘除是java程序的基本运算符,性能已经相当好了,没必要用二进制的算法。

如果你还想了解更多这方面的信息,记得收藏关注本站。