位运算相关内容整理

位运算相关内容整理

1负数

负数的右移:负数右移的话,由于要保持它是负数,所以负数的二进制的左边补1。如果一直右移的话,最后就就变成0xFFFFFFFF 即-1

如: -4>>1 为-2 ;-4>>2为-1

负数的左移:跟正整数左移一样,右边补0。左移总是在低位补零,高位丢失,因而负数左移后可能会变成正数。

int x = 0x8fff0000;

cout << (x << 1); // 输出为536739840

cout << (-2 << 31); // 输出为0

2)位运算n&(n-1)的妙用

i) 判断一个数是否是2的方幂 –-

n>0 && ((n&&(n-1)) == 0)

ii) 求某一个数的二进制表示中1的个数 --

/*fun返回值是参数n转化为二进制后包含1的数量
要注意,此例中形参的unsigned不可省略。
这是因为while循环里有n>0的比较操作,若将形参声明为int,则负数无法得到结果
【将int转化为unsigned int,并不会改变内存中数据的存储内容,只是解释不同】*/
int fun(unsigned int n) {
    int cnt = 0;
    while (n > 0) {
        n &= (n - 1);
        cnt++;
    }
    return cnt;
}

/*或者可以写成如下形式*/
// -- 推荐吧!!
int fun2(int n) {
    int cnt = 0;
    while (n != 0) {
        n &= (n - 1);
        cnt++;
    }
    return cnt;
}

iii) 计算N!的质因数2的个数

容易得出N!质因数2的个数 = [N / 2] + [N / 4] + [N / 8] + ....

下面通过一个简单的例子来推导一下过程:N = 10101(二进制表示)

现在我们跟踪最高位的1,不考虑其他位,假定都为0,

[N / 2]    01000

[N / 4]    00100

[N / 8]    00010

[N / 16]    00001

则所有相加等于01111 = 10000 - 1

由此推及其他位可得:(10101)!的质因数2的个数为10000 - 1 + 00100 - 1 + 00001 - 1 = 10101 - 3(二进制表示中1的个数)

推及一般N!的质因数2的个数为N-(N二进制表示中1的个数)

3)关于异或运算符。

i)

异或运算符有一个奇特的性质:两个相同的数异或之后结果为0,且满足交换律。即:若有A^B^C^D^E^F^B,等价于A^C^D^E^F。

这一性质常用于寻找成对出现时缺失的某一个数。

例题:给你一个由n-1个整数组成的为排序的序列,其元素都是1-n中的不同整数。请写出寻找序列中缺失整数的线性时间算法。

解答:若用n个数的和减去n-1个数的和,可能有溢出。

因此,用异或方法。首先求得n个数的异或结果,在用题中所给的序列与之前的结果求异或。最终得到的就是丢失的整数。

ii)不使用第三方变量交换两个整数a和b。

a=a^b;

b=a^b;

a=a^b;

iii)不用加减乘除做加法

int add_no_op(int num1, int num2) {
    if (num2 == 0)
        return num1;
    int sum = num1^num2;
    int carry = (num1&num2) << 1;
    return add_no_op(sum, carry);
}

iv)用位运算操作求两个数的均值

(x&y)+(x^y)>>2;

时间: 2024-07-30 20:30:22

位运算相关内容整理的相关文章

!codeforces 558C Amr and Chemistry-yy题-(位运算相关)

题意:有n个数,每次进行的操作只能是除以2或者乘以2,求这n个数转换成同一个数字所需要的最小的操作步数 分析: 乍一看题目,觉得好难,对于这种每次有两种情况求最后到达的终点的balabala的我就觉得很复杂,这道题说明其实并不可怕,至少有一部分并不可怕. 这道题的做法是暴力枚举出每个数能够走到的所有的数,记录步数,最后找交点输出最小值即可.找交点也不要想复杂了,这n个数都能到达的数就是交点,那么只需要用一个数组记录能到到达这个点的起点个数,最后起点个数等于n的就是交点,这在以每个起点出发枚举的时

Gulp-构建工具 相关内容整理

Gulp- 简介 Automate and enhance your workflow | 用自动化构建工具增强你的工作流程 Gulp 是什么? gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器:它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成: 使用它,不仅可以很愉快的编写代码,而且大大提高我们的工作效率. gulp是基于Nodejs的自动任务运行器,它能自动化地完成 javascript.coffee.sass.less.html/

位运算相关

位运算符/移位运算符 运算符 &运算符 操作数1的位 操作数2的位 &的结果位 1 1 1 1 0 0 0 1 0 0 0 0 |运算符 操作数1的位 操作数2的位 &的结果位 1 1 1 1 0 1 0 1 1 0 0 0 ^运算符 操作数1的位 操作数2的位 ^的结果位 1 1 0 1 0 1 0 1 1 0 0 0 ~运算符 操作数的位 ~的结果位 1 0 0 1 移位运算符 原因:主要用于高度优化的代码,在这些代码中,使用其他数据操作的开销太高了 示例: int var1,

一些位运算的技巧整理

1.判断符号是否相同(Math.Sign) a^b >= 0 2.求两个整数的平均值 (x + y) >> 1; 3.判断基偶(比%2要快) a & 1 结果0为偶数,为1是基数 4.判断一个数是不是2的幂 ((x&(x-1))==0)&&(x!=0)

位运算常用技巧总结(01)

基础知识 对于位运算,大家都很熟悉,基本的位操作有与(&&).或(||).非(!).异或(&)等等.在面试中经常会出现位运算相关的题,所以我就做了简单的整理,参考了很多写的很好的博客及书籍,在此一并谢过. 现在简单说一下,移位运算. 左移运算:x << y.将x左移y位,将x最左边的y位丢弃,在右边补y个0. 右移运算:x >> y.将x右移y位,这需要区分x是有符号数还是无符号数.在x是无符号数时,只需将x的最右边的y位丢弃,在左边补上y个0.在x是有符号

N皇后问题(位运算实现)

本文参考Matrix67的位运算相关的博文. 顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看. 主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析. 皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯.直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置

C++基础-位运算

昨天笔试遇到一道题,让实现乘法的计算方法,设计方案并优化,后来总结位运算相关知识如下: 在计算机中,数据是以1010的二进制形式存储的,1bytes = 8 bits,bit就是位,所以位运算就是对每个1010进行操作. 位运算有&|~^<<>>,分别是与或非异或左移右移. 与:1与不变,0与为0: 或:只有0或0为0,其他情况都为1: 非:取反: 异或:相同为0,不同为1: 左移右移:向左/右移动若干位: 乘法: 左移一位,相当于x2: 除法: 右移一位,/2; 不用申请

#C语言初学记录(位运算)

位运算 Problem Description7-1 数组元素循环右移问题 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0 ??A?1?A?N?1)变换为(A?N?M?? ?A?N?1?? A?0?? A?1?? ?A?N?M?1?? )(最后M个数循环移至最前面的M个位置).如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法? 输入格式: 每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0):

状压dp中常用的位运算式子

原址:状压dp入门 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.’&’符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.’|’符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.’^’符号,x^y,会将两个十进制数在二进制下进行异或运算,然后返回其十进制下的值.例如3(11)^2(10)=1(01). 4.’<<’符号