内容简介:前言:位运算可能在平常的编程中使用的并不多,但涉及到底层优化,一些算法及源码可能会经常遇见。今天就学习一下常用的位运算一、常用的位运算:
前言:
位运算可能在平常的编程中使用的并不多,但涉及到底层优化,一些算法及源码可能会经常遇见。今天就学习一下常用的位运算
一、常用的位运算:
& 与 AND
| 或 OR
^ 异或 XOR
&^ 位清空 (AND NOT)
<< 左移
>> 右移
二、位运算的用法:
位运算都是在二进制的基础上进行运算的,所以在位运算之前要先将两个数转成二进制
1. &
& 只有两个数都是 1 结果才为 1
例: var i uint8 = 20 var j uint8=15 求 i&j
i 转成二进制为 0001 0100, j 转成二进制为 0000 1111
0001 0100 & 0000 1111 = 0000 0100
0001 0100 对应的十进制就是 4
2. |
或 两个数有一个是 1 结果就是 1
0001 0100 | 0000 1111 = 0001 1111
0001 1111 转成十进制就是 31
故 20 | 15 = 31
3. ^
( 1 )
^ 可以作为二元运算符,也可以作为一元运算符
^ 作二元运算符就是异或,相同为 0 ,不相同为 1
如 1^1 =0, 0^0=0,1^0=1,0^1=1
0001 0100 ^ 0000 1111 = 0001 1011
故 20 ^ 15 =27
( 2 )
^ 作一元运算符表示是按位取反
^0001 0100 = 1110 1011
故结果为 235
请思想下面代码的结果:
func main() { var i uint8 = 20 fmt.Println(^i,^20) }
结果是: 235 -21
why?
其实原因很简单,一个是有符号的数一个是无符号的数
20 在编译器中默认为 int 类型,故最高位是符号位,符号位取反,所以得到的结果是负数
串联理解:负数的二进制数怎么表示?
负数的二进制数是它对应的正数按位取反得到反码,再加上 1 得到的补码
例如: 3 的二进制为 00000000 00000000 00000000 00000011
反码: 11111111 11111111 11111111 11111100
补码:反码加 1 : 11111111 11111111 11111111 11111101
故 -3 的二进制为 11111111 11111111 11111111 11111101
所以, 一个有符号位的 ^ 操作为 这个数 +1 的相反数
4. &^
作用: 将运算符左边数据相异的位保留,相同位清零
1&^1 得
0
1&^0 得
1
0&^1 得
0
0&^0 得
0
0001 0100 &^ 0000 1111 = 0001 0000
故结果为 16
5. >> 右移 和 << 左移
左移和右移算是比较常见的运算了
左移规则:
右边空出的位用 0 填补
高位左移溢出则舍弃该高位
右移规则:
左边空出的位用 0 或者 1 填补。正数用 0 填补,负数用 1 填补。注:不同的环境填补方式可能不同;
低位右移溢出则舍弃该位
例: 0001 0100 >> 1 得 0000 1010 转成十进制为 10
0001 0100 << 1 得 0010 1000 转成十进制为 40
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 深入理解new运算符
- 一道面试题引发的思考:理解 new 运算符
- [译]C++ 协程:理解 co_await 运算符
- 重学前端学习笔记(二十八)--通过四则运算的解释器快速理解编译原理
- 【Java】使用位运算(&)代替取模运算(%)
- ES6—扩展运算符和rest运算符(6)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。