C#位运算符的基本用法
位运算符包括:| 按位或 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); //6Console.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#位运算符的基本用法的更多相关文章
- 位运算符的用法 ----非(!),与(&),或(|),异或(^)
位运算符的用法 ----非(!),与(&),或(|),异或(^) 三种运算符均针对二进制 非!:是一元运算符.对一个二进制的整数按位取反,输入0则输出1,输入1则输出0. 例: 0100 -( ...
- PHP中的运算符---位运算符、递增递减运算符、三元运算符、字符串运算符、数组运算符、类型运算符、错误控制运算符
1.位运算符 位运算符用来对整型数的指定位进行置位,如果被操作数是字符串,则对该字符串的ASCII码值进行操作. 运算类型 运算符 举例 结果 按位与 & $a & $b 将$a 与 ...
- ECMAScript 位运算符
位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...
- C/C++ 位运算符
C/C++位操作运算符 操作符 功能 用法 ~ 位求反 ~expr << 左移 expr1 << expr2 >> 右移 expr1 >> expr2 ...
- C语言--位运算符
一.位运算符 1.按位与:& 1> 功能 * 只有对应的两个二进制位为1时,结果位才为1,否则为0 * 举例:10用二进制表示为1010, 7用二进制表示为0111.对两个数值进行&a ...
- Javascript中的位运算符和技巧
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...
- js 位运算符
MDN定义:位运算符将它的操作数视为32位元的二进制串(0和1组成)而非十进制八进制或十六进制数. 例如:十进制数字9用二进制表示为1001,位运算符就是在这个二进制表示上执行运算,但是返回结果是标准 ...
- JavaScript位运算符
位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...
- Java基础-位运算符Bitwise Operators
Java基础-位运算符Bitwise Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.位运算特点 位运算符分为按位与(&),按位或(|),按位异或(^ ...
随机推荐
- JavaScript中构造函数
构造函数:函数的另一种执行方法,执行后创建对象,并创建原型对象. 原型链:对象访问构造函数的指针. Function函数:函数对象. Object函数:所有创建对象的祖辈对象,也是由Function对 ...
- C#socket编程序(三)
private void ReceiveData() { bool keepalive = true; Socket s = clientSocket; Byte[] buffer = new Byt ...
- nginx+keepalived高可用服务器宕机解决方案
http://blog.51cto.com/gdutcxh/2109841 https://blog.csdn.net/winsonyuan/article/details/52784988
- contabs.js 的使用
1. 先下载两个文件 https://files.cnblogs.com/files/xiaojf/style.css https://files.cnblogs.com/files/xiaojf/c ...
- 【BZOJ】4894: 天赋
题解 这道题是求一个有向图的外向生成树 入度矩阵对应着外向生成树,出度矩阵对应着内向生成树,知道了这个就可以求出基尔霍夫矩阵了,同时n - 1阶主子式一定要删掉根节点的一行一列 代码 #include ...
- USACO 6.3 Fence Rails(一道纯剪枝应用)
Fence RailsBurch, Kolstad, and Schrijvers Farmer John is trying to erect a fence around part of his ...
- java.lang.NoClassDefFoundError: ognl/PropertyAccessor
本篇对 Web 开发中,项目部署后.开启 Tomcat 服务器 Console 控制台报错 java.lang.NoClassDefFoundError: ognl/PropertyAccessor ...
- poj2387 Til the Cows Come Home(Dijkstra)
题目链接 http://poj.org/problem?id=2387 题意 有n个路标,编号1~n,输入路标编号及路标之间相隔的距离,求从路标n到路标1的最短路径(由于是无向图,所以也就是求从路标1 ...
- 美团客户端响应式框架EasyReact开源啦
前言 EasyReact 是一款基于响应式编程范式的客户端开发框架,开发者可以使用此框架轻松地解决客户端的异步问题. 目前 EasyReact 已在美团和大众点评客户端的部分业务中进行了实践,并且持续 ...
- Revit二次开发示例:AutoStamp
该示例中,在Revit启动时添加打印事件,在打印时向模型添加水印,打印完成后删除该水印. #region Namespaces using System; using System.Collect ...