【详解】位运算符--正数及负数的位运算
链接地址:【详解】位运算符--正数及负数的位运算
位运算符的正负数计算,按位与&,按位或|,按位异或^,按位非~,左移<<,右移>>,以及涉及的码制相关知识。
一、码制
二进制数正负数三种表示法——原码;反码;补码。
二进制数的第一位是符号位,0正1负;后面是数值位,正数的原码 = 反码 = 补码,即符号位为0,位于首位,随后是二进制数的绝对值。
示例:5的原码=0 0000101; 反码= 0 0000101; 补码=0 0000101负数而言,三种表示法是不一样的。
①原码:符号位“1”+二进制数绝对值数值
②反码:符号位“1”+数值位按位取反
③补码:反码+“1”(末位)
示例:-5原码=1 0000101; 反码=1 1111010; 补码=1 1111011二进制反码和补码运算性质:
[[X]反]反=[X]原
[[X]补]补=[X]原
[X]反+[Y]反=[X+Y]反(循环进位)
[X]补+[Y]补=[X+Y]补(舍弃进位)
二、位运算符
位运算符对二进制数进行操作,以二进制运算,文章中只使用8位二进制数进行表示,不过在计算机真实使用多少位存储,读者可以自己用左右移位运算符试试。 C/C++,JAVA,都是六种位运算符,运算的内在方式一样。
位运算符 | 执行原理 |
---|---|
按位与 & | 两个操作数同时为1,结果为1 |
按位或 l | 两个操作数只要有一个为1,结果就为1 |
按位异或 ^ | 两个操作数相同,结果为0,不相同,结果为1 |
按位非 ~ | 操作数为1,结果为0;操作数为0,结果为1 |
左移 << | 二进制数整体左移,右侧空位补0 |
右移 >> | 二进制数整体右移,左侧空位补0 |
1、二元位运算符的运算
二元位运算符:& ; | ;^ ;<< ;>>
正数之间:位运算是使用他们的原码进行;
只要有负数:使用补码进行运算,如果运算结果符号位为1,那么需要求运算结果结果的补码才是答案,否则答案就是运算结果。
二元位运算符:<< ;>>
正数:左右移运算最终都为0
负数:左移最终的数值为0;右移为保证数值为负,末尾“+1”
按位与 &
两个操作数同时为1,结果为1
正数
0 0 0 0 0 1 0 0 = 4
0 0 0 0 0 1 0 1 = 5
————————
0 0 0 0 0 1 0 0 = 4 & 5 = 4
正数负数
1 1 1 1 1 1 0 0 = -4补
0 0 0 0 0 1 0 1 = 5
————————
0 0 0 0 0 1 0 0 = -4 & 5 = 4
负数
1 1 1 1 1 1 0 0 = -4补
1 1 1 1 1 0 1 1 = -5补
————————
1 1 1 1 1 0 0 0 = [-4 & -5]补; -4 & -5=[[-4 & -5]补]补 =1 0001000 = -8
按位或 |
两个操作数只要有一个为1,结果就为1
正数
0 0 0 0 0 1 0 0 = 4
0 0 0 0 0 1 0 1 = 5
————————
0 0 0 0 0 1 0 1 = 4 | 5 = 5
正数负数
1 1 1 1 1 1 0 0 = -4补
0 0 0 0 0 1 0 1 = 5补
————————
1 1 1 1 1 1 0 1 = [-4 | -5]补; -4 | -5=[[-4 | -5]补]补 =1 0000011 = -3
负数
1 1 1 1 1 1 0 0 = -4补
1 1 1 1 1 0 1 1 = -5补
————————
1 1 1 1 1 1 1 1 = [-4 | -5]补; -4 | -5=[[-4 | -5]补]补 =1 0000001 = -1
按位异或 ^
两个操作数相同,结果为0,不相同,结果为1
正数
0 0 0 0 0 1 0 0 = 4
0 0 0 0 0 1 0 1 = 5
————————
0 0 0 0 0 0 0 1 = 4 ^ 5 = 1
正数负数
1 1 1 1 1 1 0 0 = -4补
0 0 0 0 0 1 0 1 = 5补
————————
1 1 1 1 1 0 0 1 = [-4 ^ -5]补; -4 ^ -5=[[-4 ^ -5]补]补 =1 0000111 = -7
负数
1 1 1 1 1 1 0 0 = -4补
1 1 1 1 1 0 1 1 = -5补
————————
0 0 0 0 0 1 1 1 = -4 ^ -5 = 7
左移 <<
二进制数整体左移,右侧空位补0
正数
0 0 0 0 0 0 0 0 0 1 0 1 = 5
0 0 0 0 0 0 0 1 0 1 0 0 = 5<<2 = 40
负数
0 0 0 0 1 0 0 0 0 1 0 1 = -5
0 0 1 0 0 0 0 1 0 1 0 0 = -5<<2 = -40
右移 >>
二进制数整体右移,左侧空位补0
正数
0 0 0 0 0 0 0 0 0 1 0 1 = 5
0 0 0 0 0 0 0 0 0 0 0 1 = 5>>2 = 1
负数
0 0 0 0 1 0 0 0 0 1 0 1 = -5
-5>>2
0 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 1 0 0 0 1 0 末尾“+1”
1 0010010 = -5>>2 = -2
2、一元位运算符的运算
一元位运算符:~
按位非 ~
按位非 ~
正数:求取非后的二进制码的补码,就是答案
负数:对取非后的二进制码的求其补码的两个步骤颠倒求出来的,就是答案
操作数为1,结果为0;操作数为0,结果为1
正数
0 0 0 0 0 1 0 1 = 5
~5
1 1 1 1 1 0 1 0
1 0 0 0 0 1 0 1 符号位不变,取反
1 0 0 0 0 1 1 0 符号位不变,末尾加一
~5 = 1 0000110 = -6
负数
1 0 0 0 0 1 0 1 = -5
~(-5)
0 1 1 1 1 0 1 0
0 1 1 1 1 0 1 1 符号位不变,末尾加一
0 0 0 0 0 1 0 0 符号位不变,取反
~(-5) = 0 0000100 = 4
三、测试代码
大家可以复制来验证一下上文说的对不对哈哈
void test()
{
cout << "4 & 5 = " << (4 & 5) << endl;
cout << "-4 & 5 = " << (-4 & 5) << endl;
cout << "-4 & -5 = " << (-4 & -5) << endl<<endl;
cout << "4 | 5 = " << (4 | 5) << endl;
cout << "-4 | 5 = " << (-4 | 5) << endl;
cout << "-4 | -5 = " << (-4 | -5) << endl<<endl;
cout << "4 ^ 5 = " << (4 ^ 5) << endl;
cout << "-4 ^ 5 = " << (-4 ^ 5) << endl;
cout << "-4 ^ -5 = " << (-4 ^ -5) << endl<<endl;
cout << "~5 = " << ~5 << endl;
cout << "~(-5) = " << ~(-5) << endl<<endl;
cout << "5<<2 = " << (5 << 3) << endl;
cout << "-5<<2 = " << (-5 << 3) << endl<<endl;
cout << "5>>2 = " << (5 >> 2) << endl;
cout << "-5>>2 = " << (-5 >> 2) << endl<<endl;
cout << "5<<65 = " << (5 << 65) << endl;
cout << "-5<<65 = " << (-5 << 65) << endl<<endl;
cout << "5>>65 = " << (5 >> 10) << endl;
cout << "-5>>65 = " << (-5 >> 10) << endl<<endl;
}
如有不足之处,还望指正 [1]。
如果对您有帮助可以点个赞或关注,将会是我最大的动力 ↩︎
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构