完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
位运算
百度百科如下: 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作位操作的优势
运算符号 下面的a和b都是整数类型,则: [tr]含义C语言[/tr]
优先级 C语言中位运算符之间,按优先级顺序排列为 [tr]优先级符号[/tr]
概念简介以及技巧
常见的二进制位的变换操作 and运算 &
对于除0以外的任意数x,使用x&1==1作为逻辑判断即可 if (x&1==1) { }
比如第7位, 0x40转到二进制是0100 0000,代表第7位是1. if (n&0x40) { //TODO:添加你要处理的代码 }
(x >> 0) & 0x000000ff /* 获取第0个字节 */ (x >> 8) & 0x000000ff /* 获取第1个字节 */ (x >> 16) & 0x000000ff /* 获取第2个字节 */ (x >> 24) & 0x000000ff /* 获取第3个字节 */
bool isPowerOfTwo(int n) { if (n <= 0) return false; return (n & (n - 1)) == 0; }
//得到余数 int Yu(int num,int n) { int i = 1 << n; return num&(i-1); }
比如说16位二进制数A:1001 1001 1001 1000,如果来你想获A的哪一位的值,就把数字B:0000 0000 0000 0000的那一位设置为1. 比如说我想获得A的第三位就把B的第三位数字设置为1,则B为0000 0000 0000 0100,设置完之后再把A、B求与, 其结果若为0,说明A的第三位为0,其结果为1,说明A的第三位为1. 同理:若要获得A的第五位,就把B设置为0000 0000 0001 0000,之后再求与。 通常在我们的程序中,数字B被称为掩码,其含义是专门用来测试某一位是否为0的数值。
利用x=x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1会将该位变为0. int Count(int x) { int sum=0; while(x) { sum++; x=x&(x-1); } return sum; } or操作
当把二进制当作集合使用时,可以用or操作来增加元素。合并编码 在对字节码进行加密时,加密后的两段bit需要重新合并成一个字节,这时就需要使用or操作。
int Grial(int x) { int count = 0; while (x + 1) { count++; x |= (x + 1); } return count; } xor操作
void swap(int &a, int &b) { a ^= b; b ^= a; a ^= b; }
int x = -1, y = 2; bool f = ((x ^ y) < 0); // true int x = 3, y = 2; bool f = ((x ^ y) < 0); // false
将需要加密的内容看做A,密钥看做B,A ^ B=加密后的内容C。而解密时只需要将C ^ 密钥B=原内容A。如果没有密钥,就不能解密! #include #include #include #define KEY 0x86 int main() { char p_data[16] = {"Hello World!"}; char Encrypt[16]={0},Decode[16]={0}; int i; for(i = 0; i < strlen(p_data); i++) { Encrypt = p_data ^ KEY; } for(i = 0; i < strlen(Encrypt); i++) { Decode = Encrypt ^ KEY; } printf("Initial date: %sn",p_data); printf("Encrypt date: %sn",Encrypt); printf("Decode date: %sn",Decode); return 0; }
利用了二进制数的性质:x^y^y = x。我们可见,当同一个数累计进行两次xor操作,相当于自行抵销了,剩下的就是不重复的数
int find(int[] arr){ int tmp = arr[0]; for(int i = 1;i < arr.length; i++){ tmp = tmp ^ arr; } return tmp; } not操作
int reversal(int a) { return ~a + 1; }
int abs(int n) { return (n ^ (n >> 31)) - (n >> 31); } 也可以这样使用 int abs(int n) { int i = n >> 31; return i == 0 ? n : (~n + 1); }
将1左移m-1位找到第m位,得到000...1...000, n在和这个数做或运算 int setBitToOne(int n, int m) { return n | (1 << (m-1)); } 同理从低位到高位,将n的第m位置0,代码如下 int setBitToZero(int n, int m) { return n & ~(1 << (m-1)); } shl操作 & shr操作
1<
unsigned short a = 34520; a = (a >> 8) | (a << 8);
unsigned short a = 34520; a = ((a & 0xAAAA) >> 1) | ((a & 0x5555) << 1); a = ((a & 0xCCCC) >> 2) | ((a & 0x3333) << 2); a = ((a & 0xF0F0) >> 4) | ((a & 0x0F0F) << 4); a = ((a & 0xFF00) >> 8) | ((a & 0x00FF) << 8);
int getMaxInt() { return (1 << 31) - 1;//2147483647, 由于优先级关系,括号不可省略 } int getMinInt() { return 1 << 31;//-2147483648 }
//自己重写的pow()方法 int pow(int m , int n){ int sum = 1; while(n != 0){ if(n & 1 == 1){ sum *= m; } m *= m; n = n >> 1; } return sum; }
int findN(int n){ n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8 // 整型一般是 32 位,上面我是假设 8 位。 return (n + 1) >> 1; }
int nlz(unsigned x) { int n; if (x == 0) return(32); n = 1; if ((x >> 16) == 0) {n = n +16; x = x <<16;} if ((x >> 24) == 0) {n = n + 8; x = x << 8;} if ((x >> 28) == 0) {n = n + 4; x = x << 4;} if ((x >> 30) == 0) {n = n + 2; x = x << 2;} n = n - (x >> 31); return n; }
将 x 的第 n 位置1,可以通过 x |= (x << n) 来实现 set_bit(char x, int n); 将 x 的第 n 位清0,可以通过 x &= ~(1 << n) 来实现 clr_bit(char x, int n); 取出 x 的第 n 位的值,可以通过 (x >> n) & 1 来实现 get_bit(char x, int n); 如下: #define clr_bit(x, n) ( (x) &= ~(1 << (n)) ) #define set_bit(x, n) ( (x) |= (1 << (n)) ) #define get_bit(x, n) ( ((x)>>(n)) & 1 ) 综合应用 以下仅列出,感兴趣可以参考下面链接. 关于操作计数方法 计算整数的符号 检测两个整数是否具有相反的符号 计算无分支的整数绝对值(abs) 计算两个整数的最小值(最小值)或最大值(最大值),而无需分支 确定整数是否为2的幂 标志延伸
有条件地否定一个值而不分支 根据掩码合并两个值中的位 计数位设置
计算奇偶校验(如果设置了奇数位数,则为1,否则为0)
交换价值
反转位序列
模数除法(又名计算余数)
查找整数的整数对数2(又称最高位集的位置)
查找整数的对数以10为底的整数 查找整数的整数对数10 查找32位IEEE浮点数的整数对数基数2 查找32位IEEE浮点的pow(2,r)根的整数对数基数2(对于无符号整数r) 计算连续的尾随零位(或查找位索引)
通过浮法舍入到2的下一个最高幂 向上舍入到2的下一个最高幂 交织位(也称为计算莫顿数)
测试单词中的字节范围(并计算出现的次数)
按词典顺序计算下一位排列 |
|
|
|
只有小组成员才能发言,加入小组>>
3309 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9049 浏览 16 评论
4083 浏览 18 评论
1167浏览 3评论
601浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
592浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2329浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1892浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 16:20 , Processed in 1.462446 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号