位运算符包括:| 按位或 OR,& 按位与 AND,^ 按位异或 XOR,~ 取反 NOT,<< 左移 Left Shift,>> 右移 Right Shift,等等。本篇体验位运算符在C#中的应用。主要包括:

进制转换
    ※ 十进制转换成二进制
    ※ 二进制转换成十进制
| 按位或操作符
& 按位与操作符
^ 按位异或操作符
    ※ 使用^按位异或交换2个数
    ※ 使用^按位异或进行加密运算
~ 取反操作符
x << n 左移运算符
x >> n 右移运算符

进制转换

因为位运算是在二进制基础上进行的,所以进制转换是位运算的前提。

□ 十进制转换成二进制

比如,把10进制的数783转换成二进制,经过下面10个步骤。


把余数从下到上拼接起来,就是783的二进制,即1100001111。

在C#中,如果是Int16类型,意味着有16位整型数。对于783来说,如果表示成Int16类型,不足16位的话,要在前面补0,即要在1100001111补6个0,完整的表示是:0000001100001111。同样的道理,如果是Int32类型,意味着有32位整型数。

如何把-783转换成Int16类型的二进制呢?

→我们知道正数783表示成Int16类型的二进制是:0000001100001111
→在每个位置上倒转,即如果是1就变成0,反之亦然,倒转后变成:1111110011110000
→再加上1,变成:1111110011110001

□二进制转换成十进制

比如,把Int16类型的二进制数0000000100010110转换成十进制,经过下面的16个步骤。

从右向左,依次乘以2的n次方。

把所有的结果加起来:
0 + 2 + 4 + 0 + 16 + 0 + 0 + 0 + 256 + 0 = 2 + 4 + 16 + 256 = 278
所以,0000000100010110的十进制数是278。

如何把一个Int16类型的负二进制数转换成十进制呢?

比如有这样的一个二进制数:1111111111010011(Int16类型,第一位是数字1表示负数,第一位是数字0表示正数)
→每个位置上反转变成:0000000000101100
→进过计算,得到的十进制数是:44
→再加1,得到:45
→再变成负数,得到:-45

| 按位或操作符

假设,十进制数38和53进行按位或计算。
→经过计算,十进制数38的二进制表达是00100110,十进制数538的二进制表达是00110101。
→对| 按位或操作符来说,只要对应的二个二进位有一个为1时,结果就为1。

→把得到的00110111转换成十进制就是:55

如果用C#表示就是:

byte result = 38 | 53;

& 按位与操作符

假设,十进制数76和231进行按位与计算。
→经过计算,十进制数76的二进制表达是01001100,十进制数231的二进制表达是11100111。
→对& 按位与操作符来说,只要对应的二个二进位有一个为0时,结果就为0。

→把得到的 01000100转换成十进制就是:68

如果用C#表示就是:

byte result = 76 & 231;

^ 按位异或操作符

假设,十进制数138和43进行按位与计算。
→经过计算,十进制数138的二进制表达是10001010,十进制数43的二进制表达是00101011。
→对^ 按位异或操作符来说,当两对应的二进位相异时,结果为1。

→把得到的10100001转换成十进制就是:161

如果用C#表示就是:

byte result = 138 ^ 43 ;

□ 例子1:使用^ 按位异或交换2个数

int x = 4;
int y = 6;
x ^= y;
y ^= x;
x ^= y;
Console.WriteLine(x); //6
Console.WriteLine(y); //4

以上过程是这样的:
(1)x ^= y,相当于x = x ^ y
x的二进制是:00100
y的二进制是:00110
x和y进行异或,结果是:00010
x转换成十进制后,x为:2

(2)y ^= x,相当于y = y ^ x
y的二进制是:00110
x的二进制是:00010
y和x进行异或,结果是:00100
y转换成十进制后,y为:4

(3)x ^= y,相当于x = x ^ y
x的二进制是:00010
y的二进制是:00100
x和y进行异或,结果是:00110
x转换成十进制后,x为:6

□ 例子2:使用^按位异或进行加密运算

string msg = "这是我要加密的string字符串";
string k = "mypassword";
for(int i = 0; i < msg.Length; i++)
{
    sb.Append((char)(msg[i] ^ k[i % k.Length]));
}
Console.WriteLine(sb.ToString());

~ 取反操作符

假设,十进制数52进行取反计算。
→经过计算,十进制数52的二进制表达是00110100
→对~ 取反操作符来说,对应的二进位数按位求反,0变成1,1变成0

→把得到的11001011转换成十进制就是:203

如果用C#表示就是:

byte result = ~52;

x << n 左移运算符

每位向左移动n位,右边空缺的位置补0。
假设,十进制数154进行左移。

如果用C#表示就是:

byte b1 = 154;
byte b2 = (byte)b1 << 1;
Console.Writeline(b2);//结果是52,二进制是00110100

x >> n 右移运算符

每位向右移动n位,左边空缺的位置补0。
假设,十进制数155进行右移。

如果用C#表示就是:

byte b1 = 155;
byte b2 = (byte)(b1 >> 1);
Console.WriteLine(b2); // 结果: 77

总结:
| 按位或操作符来说,只要对应的二个二进位有一个为1时,结果就为1
& 按位与操作符来说,只要对应的二个二进位有一个为0时,结果就为0
^ 按位异或操作符来说,当两对应的二进位相异时,结果为1
~ 取反操作符来说,对应的二进位数按位求反,0变成1,1变成0
x << n 左移运算符,每位向左移动n位,右边空缺的位置补0
x >> n 右移运算符,每位向右移动n位,左边空缺的位置补0

参考资料:
Swapping of variables without Third Variable using XOR Logic
Understand how bitwise operators work
http://baike.baidu.com/view/9895739.htm?fr=aladdin

C#位运算符的基本用法的更多相关文章

  1. 位运算符的用法 ----非(!),与(&),或(|),异或(^)

    位运算符的用法 ----非(!),与(&),或(|),异或(^) 三种运算符均针对二进制 非!:是一元运算符.对一个二进制的整数按位取反,输入0则输出1,输入1则输出0. 例: 0100 -( ...

  2. PHP中的运算符---位运算符、递增递减运算符、三元运算符、字符串运算符、数组运算符、类型运算符、错误控制运算符

    1.位运算符 位运算符用来对整型数的指定位进行置位,如果被操作数是字符串,则对该字符串的ASCII码值进行操作. 运算类型 运算符 举例 结果 按位与 & $a & $b 将$a 与 ...

  3. ECMAScript 位运算符

    位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...

  4. C/C++ 位运算符

    C/C++位操作运算符 操作符 功能 用法 ~ 位求反 ~expr << 左移 expr1 << expr2 >> 右移 expr1 >> expr2 ...

  5. C语言--位运算符

    一.位运算符 1.按位与:& 1> 功能 * 只有对应的两个二进制位为1时,结果位才为1,否则为0 * 举例:10用二进制表示为1010,  7用二进制表示为0111.对两个数值进行&a ...

  6. Javascript中的位运算符和技巧

    ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...

  7. js 位运算符

    MDN定义:位运算符将它的操作数视为32位元的二进制串(0和1组成)而非十进制八进制或十六进制数. 例如:十进制数字9用二进制表示为1001,位运算符就是在这个二进制表示上执行运算,但是返回结果是标准 ...

  8. JavaScript位运算符

    位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...

  9. Java基础-位运算符Bitwise Operators

    Java基础-位运算符Bitwise Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.位运算特点 位运算符分为按位与(&),按位或(|),按位异或(^ ...

随机推荐

  1. Java 泛型和类型安全的容器

    使用java SE5之前的容器的一个主要问题就是编译器允许你向容器插入不正确的类型,例如: //: holding/ApplesAndOrangesWithoutGenerics.java // Si ...

  2. 使用jsplumb的一些笔记

    欢迎就是需要使用jsplumb跟正在使用jsplumb的一起讨论 欢迎私聊 1.关于jsplumb的connection的一些事件 ####connection拖动的事件 instance.bind( ...

  3. Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇

    https://www.jianshu.com/p/5bc866b9cbb9 最近因为手头上的工作做完了,比较闲,想着做一些优化.看到以前用的那一套网络框架添加一个请求比较麻烦,并且比较难用,所以想改 ...

  4. ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app

    转载:http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-a ...

  5. C++11线程池的实现

    什么是线程池 处理大量并发任务,一个请求一个线程来处理请求任务,大量的线程创建和销毁将过多的消耗系统资源,还增加了线程上下文切换开销. 线程池通过在系统中预先创建一定数量的线程,当任务请求到来时从线程 ...

  6. 8-1 binpacking uva1149(贪心)

    题意:给定N个物品的重量Li  背包的容量M 同时要求每个背包最多装两个物品 求至少要多少个背包才能装下所有物品 简单贪心  注意输出: #include<bits/stdc++.h> u ...

  7. centOS7下SVN的安装和使用

    1. 安装 CentOS通过yum安装subversion. # yum install subversion  subversion安装在/bin目录: # which svnserve #查看目录 ...

  8. 洛谷.4512.[模板]多项式除法(NTT)

    题目链接 多项式除法 & 取模 很神奇,记录一下. 只是主要部分,更详细的和其它内容看这吧. 给定一个\(n\)次多项式\(A(x)\)和\(m\)次多项式\(D(x)\),求\(deg(Q) ...

  9. 20162327WJH2016-2017-2《程序设计与数据结构》课程总结

    20162327WJH2016-2017-2<程序设计与数据结构>课程总结 一.每周作业链接汇总 第一周作业:算法分析 第三周作业:查找与排序 第五周作业:有关栈的总结 第七周作业:树的有 ...

  10. play framework系列之打包war

    概览 Play framwork 是我们一直在使用的框架,从刚开始的简单使用,乱起八糟的jar包引用,项目组成员之间的下载项目之后的引用问题等,遇到各种问题,我都一一解决,我将在这个系列中奉上解决方案 ...