C++ 中的位操作

定义二进制变量:

一般是以八进制或者十六进制来定义,八进制数以0开头,十六进制数以0x开头

例如int  a = 0x80, 这里的80只能表示8个二进制位,它表示的是int的低8位,前面的24个二进制位补0,所以a = 128;也可以
a = –0x80, 此时a = -128;8进制同理

需要注意的是:如果0x…能够在整形内表示,则其默认是int,否则再看unsigned int能否表示,接着long long ,再接着unsigned
long long (可以用cout<<typeid(0xF0).name();查看变量类型)

关于移位操作:

<< 左移位操作:从右边开始用0补空位

>>右移位操作:对于无符号数从左边开始补0;对于有符号数,或者补符号位,或者补0,由编译器决定(gcc的编译器是补符号位)

注意:移位的数目是负数或者移位出界时(最多只能移位类型二进制位大小-1),这个操作符的行为是未定义的,可以参考C++移位运算符,位操作只针对整数类型(int
long等)或者char类型的数据

常用二进制位操作(如果没强调,expr可以是无符号或有符号整数):具体请参考c_c++刁钻问题各个击破之位运算及其实例(2)

1.        将expr的第n(n从0开始)位设置为1:  expr
|= (1<<n);

2.       
将expr的第n(n从0开始)位设置为0:    expr &= (~(1<<n));

3.        判断expr的第n(n从0开始)位是否为1:bool b =
expr &(1<<n);

4.        翻转expr的第n(n从0开始)位:expr ^=
(1<<n);

5.        将最右侧的1翻转成0:expr &=
(expr-1) 
(可以用来判断二进制中1的个数,每次翻转一个1,知道数字变为0)                              
本文地址

6.        向右连续传播最右侧的1位:expr |=
(expr-1)  (该操作使00101000 变为 00101111)

7.       
检查无符号数expr是否是2的整数次幂:if((expr&(expr-1))==0)return true;
即说明expr的二进制中只有一个1

8.        将右侧的连续1位串翻转成0位串,其他保持不变:expr =
((expr|(expr-1))+1)&expr

9.       
检查无符号整数expr是否等于2的两个整数次幂之差 if(((expr|(expr-1))+1)&expr ==
0)return true;  (只要说明:无符号数二进制中所有的1都在一起)

10.     
对于整数expr,求最小的、比expr大的整数M,使得M与expr的二进制表示中有相同数目的1, 如下,具体可参考给力!高效!易懂!位运算求组合

int NextN(int N)
{
    int x =
N&(-N);     
    int t = N+x;

    return t | ((N^t)/x)>>2;
}

需要注意的是:如果没有比expr大且二进制中1相同的数,函数返回-1

11.        循环移位,以整形举例,循环左移和右移函数如下

int rotateLeft(int a, unsigned int n)//循环左移n位
{

    n %= 32;
    if(n == 0)return
a;
    return (a << n) | ((a & 0xFFFFFFFF)
>> (32 - n));
}

int rotateRight(int a, unsigned int n)//循环右移n位
{

    n %= 32;
    if(n == 0)return
a;
    return ((a & 0xFFFFFFFF) >> n) | (a
<< (32 - n));
}

例如:

a = 01111011,循环左移2位的正确结果是: b=11101101

b = a >> (8 - 2); //用来得到正常左移丢失的位和循环移位后其正确位置 //b=00000001;

a = a << 2; //a = 11101100

a = a | b; //a = 11101101

注意1:按照上面的例子,我们需要的是右移操作右边补0;但是如果输入是个负数,c++没有规定右移操作是怎么补位的,而大部分编译器是补符号位,所以此时需要把这个负数转化成无符号整数,这就是a
& 0xFFFFFFFF的作用(0xFFFFFFFF的类型是unsigned int)

注意2:当n 超过32时,需要n = n%32 这相当于循环移了好几圈;另外如果n = 0,那么32-n =
32,而整数移位操作对于大于31的移动位数是未定义的行为(见上面移位操作那部分红字注释)

【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3695166.html

C++ 中的位操作,码迷,mamicode.com

时间: 2024-10-10 21:52:21

C++ 中的位操作的相关文章

java中的位操作、移位操作

在日常开发中,其实位操作.移位操作的使用并不多,主要是其可读性较差,但是在计算密集型操作如一致性哈希计算.hashmap扩容.取数据的交集.差集.并集.权限开关位,位操作.移位操作被广泛使用.因此本文章来介绍Java中的位操作.移位操作,当然LZ特别说明我们的使用场景. 一. 相关基础概念 在开始java位运算的知识之前,我们先来了解几个基础的概念,机器数,真值,原码,反码,补码. 1.机器数 我们知道无论是代码还是数值,在计算机中最后都转换成以二进制的形式存在的,而一个数值在计算机中的二进制表

java中的位操作

之前做项目的时候使用位操作不是很多,今天在刷leetcode上题目的时候用到了位操作,是leetcode中的第29题Divide Two Integers. 一.java的位操作: 位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算.位运算符可以分为逻辑运算符(包括~.&.|和^)及移位运算符(包括>>.<<和>>>). 1)左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0).左移一位(在

netty中的位操作

看了PoolChunk源码,好多位操作,对这些位操作理解不到位,看起来很是吃力,不知道为什么要这么做,但是是性能更好 1:大小为2 的冥的数加1 怎么操作 size^1; 2: <=比较   mask=~(pageSize-1) num & mask  !=0   那么num <mask 4:两个数互补 mask= -(constNum) mask & num==0

Go基础之--位操作中你所不知道的用法

之前一直忽略的就是所有语言中关于位操作,觉得用处并不多,可能用到也非常简单的用法,但是其实一直忽略的是它们的用处还是非常大的,下面先回顾一下位操作符的基础 位操作符 与操作:&1 & 1 = 11 & 0 = 00 & 1 = 00 & 0 = 0 或操作:!1 | 1 = 11 | 0 = 10 | 1 = 10 & 0 = 0 异或:^1 ^ 1 = 01 ^ 0 = 10 ^ 1 = 10 ^ 0 = 0 左移:<<1 << 1

C语言位操作

最近在重新学习C语言,使用的书为Brian W.Kernignan 和 Dennis M.Ritchie的<C程序设计语言> .今晚读到了位操作,并写了一些简单的测试程序. C语言提供了6个位操作运算符.这些运算符只能作用于整型操作数,即只能作用于带着有符号或无符号的char.short.int与long类型. 这六种位操作运算符为: & 按位与 | 按位或 ^ 按位抑或 << 左移 >> 右移 ~ 按位求反 位操作常用于一些开关性质的操作.例如: x = x

C++:位操作基础篇之位操作全面总结

位操作篇共分为基础篇和提高篇,基础篇主要对位操作进行全面总结,帮助大家梳理知识.提高篇则针对各大IT公司如微软.腾讯.百度.360等公司的笔试面试题作详细的解答,使大家能熟练应对在笔试面试中位操作题目. 下面就先来对位操作作个全面总结,欢迎大家补充. 在计算机中所有数据都是以二进制的形式储存的.位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快. 在实际编程中,如果能巧妙运用位操作,完全可以达到四两拨千斤的效果,正因为位操作的这些优点,所以位操作在各大IT公司的笔试面试中

位操作的趣味应用

位操作有很有趣的应用,下面列举出一些,欢迎读者补充. 1.  高低位交换 给出一个16位的无符号整数.称这个二进制数的前8位为"高位",后8位为"低位".现在写一程序将它的高低位交换.例如,数34520用二进制表示为: 10000110 11011000 将它的高低位进行交换,我们得到了一个新的二进制数: 11011000 10000110 它即是十进制的55430. 这个问题用位操作解决起来非常方便,设x=34520=10000110 11011000(二进制)

位操作基础篇之位操作全面总结

文章参考地址:http://blog.csdn.net/morewindows/article/details/7354571# 位操作篇共分为基础篇和提高篇,基础篇主要对位操作进行全面总结,帮助大家梳理知识.提高篇则针对各大IT公司如微软.腾讯.百度.360等公司的笔试面试题作详细的解答,使大家能熟练应对在笔试面试中位操作题目. 下面就先来对位操作作个全面总结,欢迎大家补充. 在计算机中所有数据都是以二进制的形式储存的.位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快

位操作与空间压缩

筛素数法在这里不就详细介绍了,本文着重对筛素数法所使用的素数表进行优化来减小其空间占用.要压缩素数表的空间占用,可以使用位操作.下面是用筛素数法计算100以内的素数示例代码(注2): #include <stdio.h> #include <memory.h> const int MAXN = 100; bool flag[MAXN]; int primes[MAXN / 3 + 1], pi; //对每个素数,它的倍数必定不是素数. //有很多重复如flag[10]会在访问fla