位运算及其编程妙用

Bitwise Operators

介绍

位操作符通常用来对操作数进行位级的操作运算。首先将运算符转换为位级,然后对操作数执行计算。可以在比特级执行诸如加法,减法,乘法等的数学运算以便更快地处理。

在C语言中,有6种位操作符(在比特级运算)。

  • &(bitwise AND):与。两个操作数,在两个操作数上的每个比特上进行AND操作。只有两个比特都是1时,运算结果才是1。
  • |(bitwise OR):或。两个操作数,在两个操作数上的每个比特上进行OR操作。只要有一个比特为1,运算结果为1。
  • ~(bitwise NOT):非。单元操作符。只要一个操作数。翻转比特位-0变1,1变0.
  • ^(bitwise OXR):异或。两个操作数。在两个操作数上的每个比特上进行XOR操作。如果两个比特位不相同,运算结果为1.
  • <<(left shift):左移。两个操作数。要左移的数以及左移的位数。
  • \(>>\)(right shift):右移。两个操作数。要右移的数以及右移的位数。
#include<stdio.h> 
int main() 
{ 
    unsigned char a = 5, b = 9; // a = 5(00000101), b = 9(00001001) 
    printf("a = %d, b = %d\n", a, b); 
    printf("a&b = %d\n", a&b); // The result is 00000001 
    printf("a|b = %d\n", a|b);  // The result is 00001101 
    printf("a^b = %d\n", a^b); // The result is 00001100 
    printf("~a = %d\n", a = ~a);   // The result is 11111010 
    printf("b<<1 = %d\n", b<<1);  // The result is 00010010  
    printf("b>>1 = %d\n", b>>1);  // The result is 00000100  
    return 0; 
} 

运算结果:

a = 5, b = 9
a&b = 1
a|b = 13
a^b = 12
~a = 250
b<<1 = 18   
b>>1 = 4

特性

  1. 左移和右移操作符不能用在负数上。如果两个操作数其中一个为负数,将会导致undefined行为。如-1<<1 或1<<-1.而且,如果移动的位数超过数的范围,也会导致undefined行为。如1<<33. 出错。
  2. 从面试上说XOR异或操作是最常见的知识点。主要性质:任意数和自身异或结果为0;0和任意数n异或结果还是本身n. eg:“Given a set of numbers where all elements occur even number of times except one number, find the odd occurring number.”给一个数组,数组元素除了一个元素外都出现偶数次,找到出现奇数次的元素。
int findOdd(int arr[], int n)
{
    int res = 0,i;
    for(i=0;i<n;i++)
        res ^= arr[i];
    return res;
}
  1. 位操作符不能用来替换逻辑运算符。逻辑运算符(&&,||,和!)运算结果为0或1.但位操作符运算结果为整数。而且逻辑运算符将任意非0值视为1.
  2. 左移和右移分别等价于乘2和除以2.
  3. & 运算符可以用来快速检测一个数的奇偶性. x & 1表达式的值如果非0,则x是奇数;反之为偶数。
int main(){
    int x = 19;
    (x & 1)? printf("Odd"):printf("Even");
    
    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黑泽君的专栏

调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Thread-2、...呢?

调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Th...

15420
来自专栏深度学习与计算机视觉

算法-从尾到头打印链表

题目: 输入一个链表,要求从尾到头打印该链表,链表结点定义如下: struct ListNode { int value; ListNode *ne...

20090
来自专栏猿人谷

struct 与 typedef struct

1. 基本解释   typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(...

24360
来自专栏hbbliyong

Python正则进阶

  返回一个列表,如果正则表达式中没有分组,则列表中包含的是所有匹配的内容,如果正则表达式中有分组,则列表中的每个元素是一个元组,元组中包含子分组中匹配到的内容...

15230
来自专栏Micro_awake web

JavaScript(四):运算符&数据类型转换

+:算符的加法;连接字符串 加法会将其它类型的值,自动转为字符串,然后再进行连接运算! 1 var a=1+2; 2 console.log('first:...

20460
来自专栏数据结构与算法

归并排序

将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(有序表),这种操作称为归并操作。这样的方法经常用于多个有序的数据文件归并成一个有序的数据文件。...

28760
来自专栏尾尾部落

[剑指offer] 数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。

20620
来自专栏Bingo的深度学习杂货店

Q190 Reverse Bits

Reverse bits of a given 32 bits unsigned integer. For example: given input 43261...

34750
来自专栏Java帮帮-微信公众号-技术文章全总结

04-01.总结switch,for,while,do。while跳转语句

1:switch语句(掌握) (1)格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; ...

38850
来自专栏用户画像

7.3.2 快速排序

快速排序是对冒泡排序的改进。其基本思想是基于分治法:在待排序L[1...n]中任取一个元素privot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1....

7130

扫码关注云+社区

领取腾讯云代金券