C/C++学习笔记:按位运算基本知识及用法介绍
/*按位运算,见 C Primer Plus 中文第六版 第497页 补码的概念:
在补码表示中,最高位为符号位,正数的符号位为0,负数为1
补码的规定如下:
对正数来说,最高位为0,其余各位代表数值本身(以二进制表示),如+42的补码为00101010。
对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。如-42的补码为11010110(00101010按位取反11010101+1即11010110)
用补码来表示数,0的补码是单一的,都为00000000。(而在原码,反码表示中,+0和-0的表示是不单一的)。而且可以用111111表示-1的补(这也是补码与原码和反码的区别)。1、二进制反码或按位取反:~将1变为0,0变为1,例如:~(10011010)计算之后得:(01100101) 2、按位与:&
二元运算符&通过逐位比较两个运算对象,生成一个新值,对于每个相应的位,都为1时,结果才为1
例如: (10010011)&(00111101)
-----------------
ans: 00010001
按位与运算符合计算后不再改变的变化规律:a & b & a = b & a & a3、按位或:|
二元运算符按位或|,通过比较两个运算对象,生成一个新值,对于相应的位存在1,那么值为1
例如: (10010011)|(00111101)
-----------------
ans: 10111111
按位或运算符合计算后不再改变的变化规律:a | b | a = b | a | a4、按位异或:^
二元运算符按位异或^,逐位比较两个运算对象,对于一个相应位,如果只有一个1,那么值为1,否则值为0;
可以理解为:无进位相加,即不考虑进位的时候将对应值相加
例如: (10010011)^(00111101)
-----------------
ans: 10101110
异或运算符合交换律和结合律:
a ^ b = b ^ a;
a ^ a = 0;
0 ^ a = a;
a ^ b ^ a = b ^ a ^ a = b;
因此通常用来交换两个变量的值:例如交换a和b的值,我们可以这样计算:
a = a ^ b;
b = a ^ b;
a = b ^ a;
*//*
常用算法之提取二进制中最右侧的1:
例如 获取 二进制数 010010101000 中最右侧的1,即获得 000000001000
解法:利用公式 a&(~a+1)即可 公式中的&和~都是按位运算符
a= 010010101000
~a= 101101010111
~a+1= 101101011000
b=a&(~a+1)= 000000001000
因此,按照此规律,可以处理原数的倒数第二个1:
a'=a-b= 010010100000
....周而反复,可以提取每一个1
*//*
常用算法之 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数:
例如 112222333344444444555 中5只出现了一次,则利用异或运算的规律,任何数对自己异或运算,结果均为0,即a ^ a = 0;
因此可以通过将所有值进行异或运算,即可获得5为出现奇数次的那个数。*//*
常用算法之 计算一个数字除以2:
只需要对它进行右移一位即可: (a / 2) == (a >> 1); 对正数负数都成立
*/#include <iostream>
#include <cmath>
using namespace std;void Bitewise_Negation(); //按位取反运算函数
void Bitewise_EXCLUSIVE_OR();//按位异或^运算函数
void Bitewise_OR(); //按位或|运算函数
void Bitewise_AND(); //按位与&运算函数int main()
{Bitewise_EXCLUSIVE_OR();Bitewise_OR();Bitewise_AND();Bitewise_Negation();return 0;
}void Bitewise_EXCLUSIVE_OR()//按位异或^运算函数
{int a = 5;int b = 6;
/* 我们来看看按位异或^实际运算过程(00000101) //5的二进制^(00000110) //6的二进制-----------------ans: 00000011 //计算结果为3的二进制
*/cout << "a = 5,b = 6,则(a ^ b) = " << (a ^ b) << endl;cout << "a = 5,b = 6,则((a ^ b) ^ a) = " << ((a ^ b) ^ a) << endl;cout << "a = 5,b = 6,则((b ^ a) ^ a) = " << ((b ^ a) ^ a) << endl;cout << "a = 5,b = 6,则(b ^ (a ^ a)) = " << (b ^ (a ^ a)) << endl;cout << "a = 5,b = 6,则((a ^ a) ^ b) = " << ((a ^ a) ^ b) << endl;cout << "a = 5,b = 6,则(a ^ b ^ a) = " << (b ^ a ^ a) << endl;cout << "a = 5,b = 6,则(b ^ a ^ a) = " << (b ^ a ^ a) << endl; cout << "结论:按位异或运算符合分配律:a ^ b ^ a = b ^ a ^ a = b;" << endl;cout << "=================================" << endl;
}
void Bitewise_OR() //按位或|运算函数
{int a = 5;int b = 6;
/* 我们来看看按位或|实际运算过程(00000101) //5的二进制|(00000110) //6的二进制-----------------ans: 00000111 //计算结果为7的二进制
*/cout << "a = 5,b = 6,则(a | b) = " << (a | b) << endl;cout << "a = 5,b = 6,则((a | b) | a) = " << ((a | b) | a) << endl;cout << "a = 5,b = 6,则((b | a) | a) = " << ((b | a) | a) << endl;cout << "a = 5,b = 6,则(b | (a | a)) = " << (b | (a | a)) << endl;cout << "a = 5,b = 6,则((a | a) | b) = " << ((a | a) | b) << endl;cout << "a = 5,b = 6,则(a | b | a) = " << (b | a | a) << endl;cout << "a = 5,b = 6,则(b | a | a) = " << (b | a | a) << endl; cout << "结论:按位或运算符合计算后不再改变的变化规律:a | b | a = b | a | a ;" << endl;cout << "=================================" << endl;
}
void Bitewise_AND() //按位与&运算函数
{int a = 5;int b = 6;
/* 我们来看看按位与&实际运算过程(00000101) //5的二进制&(00000110) //6的二进制-----------------ans: 00000100 //计算结果为4的二进制
*/cout << "a = 5,b = 6,则(a & b) = " << (a & b) << endl;cout << "a = 5,b = 6,则((a & b) & a) = " << ((a & b) & a) << endl;cout << "a = 5,b = 6,则((b & a) & a) = " << ((b & a) & a) << endl;cout << "a = 5,b = 6,则(b & (a & a)) = " << (b & (a & a)) << endl;cout << "a = 5,b = 6,则((a & a) & b) = " << ((a & a) & b) << endl;cout << "a = 5,b = 6,则(a & b & a) = " << (b & a & a) << endl;cout << "a = 5,b = 6,则(b & a & a) = " << (b & a & a) << endl; cout << "结论:按位与运算符合计算后不再改变的变化规律:a & b & a = b & a & a ;" << endl;cout << "=================================" << endl;
}void Bitewise_Negation() //按位取反运算函数
{//int a = 2147483647; // 2^31 - 1 ; /* 我们来看看按位或|实际运算过程~(00000101) //5的二进制-----------------ans: 11111010 //计算结果为-6的二进制,对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。
*/int sum = 0;int a = 0;cout << "sizeof(int) = " << sizeof(int) << endl;/*11111111111111111111111111111111 --> 2^30 + 2^29 + ...... + 2^1 + 2^0 */for (int i = 0; i < (sizeof(int) * 8 -1); i++){a += pow(2,i);// a = a + pow(2,i);}cout << "2^30 + 2^29 + ...... + 2^1 + 2^0 = " << a << endl;cout << "2^30 + 2^29 + ...... + 2^1 + 2^0 + 1 = " << a + 1<< endl; // a + 1为负数cout << "经过计算,2147483647 + 1 = 2147483647,则就可以证明:int类型的最大值是2147483647,说明首位是符号位"<< endl;cout << "(unsigned int)pow(2,50) = " << (unsigned int)pow(2,50) << endl;// 最大值只能获取到2147483648cout << "(unsigned int)pow(2,32) = " << (unsigned int)pow(2,32) << endl;// 最大值只能获取到2147483648cout << "(unsigned int)pow(2,31) = " << (unsigned int)pow(2,31) << endl;// 最大值只能获取到2147483648cout << "(unsigned int)pow(2,30) = " << (unsigned int)pow(2,30) << endl;// 1073741824
/* 我们来看看按位或|实际运算过程~(01111111111111111111111111111111) //2147483647的二进制-------------------------------------------------------------------------------------ans: 10000000000000000000000000000000 //计算结果为-2147483648的二进制:对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。~(00000000000000000000000000000001) //1的二进制-------------------------------------------------------------------------------------ans: 11111111111111111111111111111110 //计算结果为-2的二进制:对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。
*/cout << "a = " << a << ",则 ~a = " << ~a << endl;cout << "a = " << a << ",则 ~a = " << ~~a << endl;cout << "对0取反:~0 = " << ~0 << endl; // 注意,在计算机中,没有-0cout << "对1取反:~1 = " << ~1 << endl; //对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。cout << "对2取反:~2 = " << ~2 << endl; //对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。cout << "对3取反:~3 = " << ~3 << endl; //对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。cout << "对3取反:~4 = " << ~4 << endl; //对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。cout << "对3取反:~5 = " << ~5 << endl; //对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。//cout << "=================================" << endl;
}
C/C++学习笔记:按位运算基本知识及用法介绍相关推荐
- C++学习笔记-----用位运算实现加减乘除
C++学习笔记-----用位运算实现加减乘除 原文:http://blog.csdn.net/sinat_35261315/article/details/72904945 数据在计算机内存中是以二进 ...
- c语言用位运算将一个数清零,C语言学习笔记_位运算
C语言学习笔记_位运算 知识点记录 基本位运算 按位与:全1为1,见0为0:与1相与无变化,与0相与变为0:可用于特定位清零 按位或:见1为1,全0为0:与1相或变为1,与0相或无变化:可用于特定位置 ...
- 算法学习笔记(5)-------位运算的tips
为什么80%的码农都做不了架构师?>>> 在计算机中所有数据都是以二进制的形式储存的.位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快. 在实际编程中 ...
- 数据结构与算法XS班-左程云第一节课笔记(位运算、算法是什么、简单排序)
第1节 位运算.算法是什么.简单排序 ##这是数据结构与算法新手班-左程云第一节课的笔记## 1. 位运算 // 你们会不会表示一个数字的32位啊? // Java中int类型默认以32位二进制数在计 ...
- 基础才是王道——TCP/IP详解学习笔记 这位仁兄写得太好了
TCP/IP详解学习笔记 这位仁兄写得太好了 TCP/IP详解学习笔记 这位仁兄写得太好了. http://blog.csdn.net/goodboy1881/category/204448.as ...
- Polyworks脚本开发学习笔记(六)-比较运算、数学运算、逻辑运算及流程控制
Polyworks脚本开发学习笔记(六)-比较运算.数学运算.逻辑运算及流程控制 前言 比较运算.逻辑运算及流程控制是编程的基本语法,Polyworks的语法规则与VB/C#/Python等并没有很大 ...
- Apollo学习笔记3-定位模块配置
Apollo学习笔记3-定位模块配置 环境介绍 导航设备参数配置 导航设备配置 (1)杆臂配置 (2)GNSS 航向配置 (3)导航模式配置 (4) USB 接口输出设置 (5)网口配置 (6) PP ...
- 【Python学习笔记】第一章基础知识:格式化输出,转义字符,变量类型转换,算术运算符,运算符优先级和赋值运算符,逻辑运算符,世界杯案例题目,条件判断if语句,猜拳游戏与三目运算符
Python学习笔记之[第一章]基础知识 前言: 一.格式化输出 1.基本格式: 2.练习代码: 二.转义字符 1.基本格式: 2.练习代码: 3.输出结果: 三.输入 1.基本格式: 2.练习代码: ...
- MATLAB学习笔记2:MATLAB基础知识(下)
阅读前请注意: 1. 该学习笔记是华中师范大学HelloWorld程序设计协会2021年寒假MATLAB培训的学习记录,是基于培训课堂内容的总结归纳.拓展阅读.博客内容由 @K2SO4钾 撰写.编辑, ...
最新文章
- origin数据平滑_独门绝技!Origin挑战绘制细胞分化轨迹热图
- 手机微站webapp
- Java多线程知识小抄集(四)——完结
- .Net Core使用Ocelot网关(二) -鉴权认证
- 什么是通用字符名称?_通用名称
- bug--Unable to add window –token is not valid; is your activity running?
- 惠普服务器查看主板型号,win10惠普主板型号查看图文教程
- Python学习笔记(尚硅谷)——变量
- 作为程序员的你,除了撸代码,还能干什么?
- 关于个人博客的相关内容
- STC学习:485双机通信
- Odoo15企业邮箱配置与实现手机端回复亦可自动挂单
- java 九宫格数独,(完整)九宫格数独题目大全,推荐文档
- 【精品软件】鼠标右键菜单设置管理工具
- html五星评分标准,五星级酒店评分标准.doc
- switchport nonegotiate
- 【devops】非必要 不要自建harbor 能力不足 真的被坑的服了 阿里云ACR不香吗?k8s接入ACR
- 安全存储,ARM HUK
- 前端开发之JS篇(二)
- React 动效 Framer motion,给你的页面添加一点动感