OIer应该知道的二进制知识
计算机使用\(2\)进制,这是众所周知的。在学习\(OI\)的过程中,\(2\)进制也显得尤为重要。有时候,细节决定成败,所以我想总结一下容易被遗忘和误解的关于\(2\)进制的知识。
1、运算符
&:与。1&1=1,1&0=0,0&0=0;(同真为真)
|:或。1|1=1,1|0=1,0|0=0;(一真俱真)
^:异或。1 ^ 1=0,1 ^ 0=1, 0 ^ 0=0;(阴阳协调为好,极阴或极阳皆为坏)
num>>len:将num左移len位,低位溢出舍弃,高位不足补0。比如1010>>3就等于0001
num<<len:将num右移len位,高位溢出舍弃,低位不足补0。比如1010<<3就等于0000
~:全位取反。比如 ~ 1010=0101
位运算优先级要比加减乘除等运算优先级低,所以用的时候记得加括号。
2、原码,补码,反码
对于这三个东西我并不是很清楚他们分别是什么意思,在\(OI\)中,我觉得记住下面几点就可以了。
二进制数的第一位表示符号,\(0\)为整数,\(1\)为负数。\(int\)作为一个\(32\)位整形数据类型可以保存\([-2^{31}-1,2^{31}-1]\)的所有整数。因为第一位存符号去了,所以只是到\(2^{31}\)而不是\(2^{32}\)。\(unsigned\) \(int\)不保存符号位就可以到\(2^{32}\)。\(long\) \(long\)同理。所谓溢出就是数值超过\(32\)位二进制数能存的范围(\(64\)位同理,我们以\(int\)为例)。比如\(01111111111111111111111111111111\)(十进制下是\(2147483647\))也就是\(int\)能保存的最大的数字。加上一个\(1\)之后理应是\(2147483648\),二进制下就是\(10000000000000000000000000000000\)。但是因为第一位是符号位,所以就变成负数了。而每个数逐位取反都是自己的相反数\(-1\),所以\(~2147483647=-2147483648\)。再举几个例子:
比如\(-1(11111111111111111111111111111111)\)取反之后就是\(0(000000000000000000000000)\)。所以我们也可以由这一点快速求出一个数的相反数,就是逐位取反之后再\(+1\),也就是\(~num+1=-num\)
比如~\(1(00000000000000000000000000000001)+1=-1(11111111111111111111111111111111)\)
3、lowbit
\(lowbit(i)\)表示\(i\)在二进制下从低位到高位第一个\(1\)与它后边跟着的\(0\)是多大。比如\(lowbit(24[11000])=8[1000]\)
显然,我们会一种\(O(logn)\)的求法求\(lowbit(i)\)。但是运用上面的知识,我们可以\(O(1)\)求\(lowbit(i)\)
假设某个数二进制表示下后面一段是\(1000..000\),前面我们不管。把它逐位取反就变成了前面一段取反加上\(011111...111\)。这个时候两个数&起来是等于\(0\)的,因为没有哪个位置同为\(1\)。假设我们把取反之后的数字\(+1\)。那么就会变成原数前面一段取反加\(100....000\)。这个时候&起来,前面是反的,全部都会变成\(0\),刚刚好\(lowbit(i)\)所求的部分会被保存下来,所以\(lowbit(i)=i\)&\(((\)~\(i)\)+1\()\)。也就是\(lowbit(i)=i\)&\((-i)\)
4、memset
在很久以前我就疑惑过,为啥\(int\)类型占\(4\)字节,\(long\) \(long\)占\(8\)字节。我们可以灵性的理解一波,在二进制下,每八位占一个字节。而\(memset\),可以将某个数的每八位全部赋值成一样的数字。比如\(memset(a,1,sizeof(a))\)。就是把\(a\)数组里的每一个值都赋值成\(00000001000000010000000100000001\)。\(memset(a,255,sizeof(a))\)就是把\(a\)数组里的每一个数值都赋值成\(111111111111111111111111\)。\(0x7F\),是一个十六进制数,表示\(16^1*7+16^0*15=127\)。\(0x\)放在前面起声明这是个十六进制数的作用。由于\(2\)位十六进制数相当于\(8\)位二进制数,所以我们一般在\(memset\)里写两位十六进制数。\(memset(a,0x7F,sizeof(a))\)是将\(a\)数组全部赋值成为\(01111111011111110111111101111111\),这是\(memset\)能赋值出的最大的有符号类型整数。\(0x3F\)=\(16^1*3+16^0*15=63\),相对于\(0x7F\),这个数字更加不容易加爆,所以后面涉及加法的情况下,我们还是有\(memset(a,0x3f,sizeof(a))\)比较好。
OIer应该知道的二进制知识的更多相关文章
- 二进制知识(java中的位操作)
文章目录 前言 机器数 真值 原码 反码 补码 计算机中保存的都是补码 位操作 强制转换,精度丢失 前言 讲二进制的东西,必须要说明是多少位机器,八位机上的 1000 1000 和 十六位机上的 10 ...
- 史上最全NOIP初赛知识点
CSP-J/S 第一轮知识点选讲 \(NOIP\)(全国青少年信息学奥林匹克竞赛)于2019年取消.取而代之的是由\(CCF\)推出的非专业级软件能力认证,也就是现在的\(CSP-J/S\).作为一名 ...
- 史上最全的CSP-J/S 第一轮知识点
CSP-J/S 第一轮知识点选讲 \(NOIP\)(全国青少年信息学奥林匹克竞赛)于2019年取消.取而代之的是由\(CCF\)推出的非专业级软件能力认证,也就是现在的\(CSP-J/S\).作为一名 ...
- (转)我看PhD by 王珢
我看PhD by 王垠 前段时间看了一下这些关于 PhD 的负面信息: 一个专门反对读 PhD 的 BLOG 叫“100 Reasons NOT to Go to Graduate School”(下 ...
- Codeforces437 B. The Child and Set
题目类型:位运算 传送门:>Here< 题意:给出\(sum和limit\),求一个集合\(S\),其中的元素互不相同且不超过\(limit\),他们的\(lowbit\)之和等于\(su ...
- java 理解有符号数和无符号数
转至:http://jinguo.iteye.com/blog/212049 理解有符号数和无符号数负数在计算机中如何表示呢? 这一点,你可能听过两种不同的回答. 一种是教科书,它会告诉你:计算机用“ ...
- 《Java从入门到失业》第一章:计算机基础知识(一):二进制和十六进制
0 前言 最近7年来的高强度工作和不规律的饮食作息,压得我有些喘不过气,身体也陆续报警.2018年下半年的一场病,让我意识到了这个问题的严重性,于是开始强制自己有规律饮食和作息,并辅以健身锻炼,不到2 ...
- pta L2-002 链表去重 +散列表知识小普及+二进制取反补码运算
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805072641245184: 废话:今天忙着学习新知识了,没怎 ...
- java基础知识-二进制
1.二进制<0B>出现的原因 2. 八进制<0>和十六进制<0X>出现的原因:简化书写和记忆 3.十进制到其他进制的转换方法 method:除以进制数,直到商为0, ...
随机推荐
- sharding-jdbc从入门到出门(03)
经过端午节这2天对 sharding-jdbc一直怀揣成梦想的去学习,还是有一些没有解决的问题: 上一张图:
- Python菜鸟之路:Python基础(二)
一.温故而知新 1. 变量命名方式 旧的方式: username = 'xxxx' password = 'oooo' 新的方式: username, password = 'xxxx', 'oooo ...
- 关于Ninja中上传下载文件
上传得时候 根据类型来判断一下: 然后下载的时候需要:在url的最后一个/ 后面加上你要下载的类型如/download/app.apk; 下载成功就是app.apk了;
- C#窗体互动
说白了就是在一个窗体操作另外一个窗体的东西. 原理是把form2的数据提取出来,利用中间的静态类middle来传递数据,触发事件,调用委托,来修正form1 效果如下: Form1.cs usin ...
- CAS的实现Atomic类库
atomic 原子(atomic)本意是"不能被进一步分割的最小粒子",而原子操作(atomic operation)意为"不可被中断的一个或一系列操作".在多 ...
- iOS UIImage 图片局部拉伸的一些学习要点
之前 做纯色局部拉伸 通过 top bottom left right 相交的阴影拉伸 屡试不爽 实施方法: imageView.image = [[UIImage imageNamed: @&q ...
- 培训笔记——Linux基本命令
在介绍命令之前,更重要的要先介绍一下快速输入命令的方法. 如果你能记住一些常用命令,毫无疑问,通过命令的操作方式比通过鼠标的操作方式要快. 但是有一些命令或是命令用到的参数如文件名特别复杂特别长,这时 ...
- Linuxshell资料汇总
1.判断文件是否存在 https://www.cnblogs.com/platero/p/4021561.html 2.日期赋值 https://www.cnblogs.com/lonelywolfm ...
- python 3 递归调用与二分法
递归调用与二分法 1.递归调用 递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身. 示例: def age(n): if n == 1: return 18 # 结束条件 return a ...
- python中reduce()函数
reduce()函数也是Python内置的一个高阶函数.reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收 ...