本篇终于说到琪姐文章中经常出现的分界线啦!归根结底,计算机就是0和1,所有的数字都以二进制的形式存在内存中。位操作,简称位操作,就是直接对内存中的二进制位进行操作。位操作可以说是我们的基本功。今天,本文将从以下几个角度带大家玩转。二进制有什么用?原码反码和补码的位运算一共有7种位运算当然有很多技巧和窍门。如果还想看进阶文章,记得给我点个赞或者留言告诉我哦~二进制在实际生产中的作用,二进制是用来优化时间和空间的。二元运算可能不会降低复杂度,但可以降低复杂度前面的系数。例如。大家都知道堆,也就是优先级队列,一般是用一棵完全二叉树来实现的,称为二叉堆。在最小堆二叉堆中插入和删除元素的时间复杂度为O(logn)。如果有不明白的,请在公众号回复“堆”复习,或者点这里~但是还有一种堆,它可以在O(1)时间插入元素,在O(1)时间删除元素登录)时间。正如我在关于堆的文章中提到的,它是斐波那契堆。但为什么不呢?因为O(1)前面的系数很大。我们说O(logn)优于O(1),有一个条件,就是当n非常非常大的时候,但实际上如果n在int的范围内,那么取log只是32,反之,这个O(1)的时间复杂度可能达到几百上千。一般来说,实际应用中对时间的度量并不像时间复杂度那么简单。有时您需要同时实现这两种算法并运行以测量它们的时间以决定哪个更好。然后二进制可以一次作用于32位(假设它是一个int)。如果数据表示巧妙,这可以优化32倍。使用更多的整数将优化数32次。不好吗?除了优化时间,还可以优化空间。例如,当网站发布新版本时,通常会附上支持该版本的浏览器列表。否则,一些旧浏览器看不到我的新功能是我的错吗?那么如何有效地表示这个浏览器列表呢?世界上所有的浏览器都有一个国际标准编号。这里我简单假设:0表示QQ浏览器,1表示Chrome浏览器,2表示Firefox浏览器,3表示...那么我们可以用一个int表示是否支持32种浏览器的状态,如果浏览器可以使用,那么这个位设置为1,那么比如国内的某个网站可以表示为:0b....1101,所以位运算在很多代码中都是常用的,比如网络协议,操作系统等等.接下来说说具体的知识点。原码反码补码数可以是正数也可以是负数,Java中使用有符号类型,即正数或负数。虽然在Java8之后,使用了一个工具来实现unsigned类型,但实际上底层实现并不存在。二进制中最左边的位是符号位,0表示这个数是非负数;1表示数字为负数。顺便说一句,左边那个在英文里叫做mostsignificantbit,很多同学在面试的时候说了各种各样的话。..正数和正数的反码和补码是一样的,没什么好说的。例如:int1=0b0000000000000001int2=0b0000000000000010负数:原码:将对应正数的符号位设置为1。原码-1=0b1000000000000001-2原码=0b1000000000000010个的补码:符号位为1,其余位取反。-1的补码=0b1111111111111110-2的补码=0b1111111111111101补码补码+1。-1的补码=0b1111111111111111-2的补码=0b111111111111计算机为1110实际上用来存储数据的是补码。这里要注意one's补码和补码的英文,'ofones'在后面,'oftwo's在中间。.为什么计算机使用二进制补码来存储数据?可能有同学会说,正零负零是有原因的,但这只是表面现象。事实上,通过补码的精妙设计,计算机在进行加减乘除运算时无需考虑符号,可以使CPU在硬件上的设计变得极其简单。起初,计算机只有加法器,没有减法器,所以用这样的方法用加法来完成减法。int的最大值是多少?正是因为最左边的位是符号位,所以正数的表示少了一位可用,那么int的最大值为:0111111...11(31个)=2^31-1=21474836477种位运算符中英文运算规则<<左移左移右补0>>右移有符号右移左补符号位>>>无符号右移unsighed右移Java专用,左补0~bitnotNOTInverse&bit和按位AND对每一位做AND运算,如果全为1则为1,否则为0I位或OR每个位做OR运算,如果有1则为1,否则为0^XORXOR相同,是0,不同需要注意的是,前4个运算符对1个数进行运算,运算完成后该数本身的值不变;最后3个操作是对两个数字的操作。让我们一一看看。为了写的方便,下面的值虽然都是int类型,但是我只写了8位,大家看得懂!1.<<左移操作就是将这些0和1全部向左移动n位,右边缺失的用0补上。1=0b000000011<<1=0b00000010=22=0b000000102<<1=0b00000100=43=0b000000113<<1=0b00000110=6哎,大家发现没有,左移一位后,这个数就相当于乘以乘以2。但这仅在左溢出的高位不包含1时有效。如果丢了1次,那一定不是2次。2.>>1=0b000000011>>1=0b00000000=02=0b000000102>>1=0b00000001=13=0b000000113>>1=0b00000001=1同理,右移操作效果是将数字除以2。如果是负数怎么办?-3=11111101-3>>1=11111110=-2因为Java向零四舍五入,所以取奇数的时候会有问题,不再是除以2的结果。总结一下,对于非负数、负数和偶数,右移一位等于除以2;对于负数和奇数,右移一位不等于除以2。3.>>>和>>的区别关键是这个左边总是补0,不管是不是正面或负面。因此它与>>对于正数的作用相同,但对于负数则不同。-3=11111101-3>>1=011111110=非常大的数字。.4、~取反运算就是对每一位取反,1变成0,0变成1。3=0b00000011~3=0b111111005符号&其实和逻辑与运算&&一样,只是Acts在每一位上。对于每一位,如果两个数都为真,则为真,否则为假。3=0b000000115=0b000001013&5=0b000000016。|同样,它与逻辑或||具有相同的含义,只是它作用于每一位。对每个人来说,只要有一个真理就是真的,否则就是假的。3=0b000000115=0b000001013|5=0b000001117。^最后的异或运算,相同为0,不同为1。3=0b000000115=0b000001013^5=0b00000110顺便说一句,这个周末新建了一个国内读者交流群。想进群的朋友会在后台回复“进群”拉你进群~另外,8月自习室活动的最后一周。让自习室的小伙伴们加油吧。应该有很多小伙伴。小伙伴可以获得琪姐的红包,21天没学够的小伙伴们要继续努力哦!9月份的自习室正在筹备中。如果你想参加,请告诉我你想在9月份学习多少天,每天学习多长时间。让我们一起学习,一起致富!~
