0.前言
刷Leetcode16题碰到计算机基础知识(>>运算和&运算,其实快速幂就够我喝一壶的了...),作为一个半路出家的和尚,这方面很薄弱,多方查找资料,总结一下,便于日后复习巩固。
1.原码、反码和补码
原码:十进制数字的绝对值转为二进制数字。这里分别以byte和int类型为例:
- byte:8位二进制,数字11的原码是0000 1011
- int: 32位二进制,数字11的原码是28个0 1011 对于负数来说,其原码除第一位是1(第一位就是符号位)之外,与绝对值原码相同,例如-11的原码是1000 1011(byte)。
顺手贴一张图片吧,十进制转二进制。
反码:正数的反码和原码相同(补码也相同);负数的反码和原码按位取反,符号位不变!!
- 11的反码还是0000 1011 而-11的反码是1111 0100。
这里顺便说一下byte的取值范围。byte是一个字节,8位二进制,共有256种可能性,即[-128,127],其中负数128个,非负数128个。
8位二进制第1位表示符号,则剩下7位表示数字(7个1),最大为27-1(这里是利用等比数列求和),也就是127。这就意味着,正数最大为127,但还有一个问题就是1000 0000(补) 总不能算作-0吧,因此多了一个数字-128。
补码是最重要的,因为计算机中存储的是补码。为什么进行补码存储,这里有介绍。 验证一下:a=-1在计算机中存储为32个1。
- 按照原码计算,这应该是 -(1+2+4+...+230);
- 按照反码计算,先转化为原码1000 0000 0000 0000 ...;
- 按照补码计算,转化反码再转化为原码1000 0000 ... 0001 = -1。
2.位运算符
在计算机内的加减都是通过补码进行运算的,其实对于操作人员来讲,不需要过分关注计算机的实现,可以作为黑箱,我们只需要关注逻辑就行,剩下的计算,电脑都解决了。
但是,在java中存在几个位运算还是需要掌握的。
2.1<< 左移运算 and >> 右移运算
以下规律为正数情况下成立:
- 左移: <<1相当于×2;<<2相当于×4;<<3相当于×8;以此类推,
- 右移: >>1相当于/2;>>2相当于/4;>>3相当于/8;以此类推, 注:无论左移还是右移都是对补码的运算;正数右移,高位用0补;负数右移,高位用1补;如果是左移都用0补。
2.2无符号右移>>>
当负数使用无符号右移时,用0进行补位(自然而然的,就由负数变成了正数了) 而正数的无符号右移与>>规律相同。
2.3位与 and 位或 and 位异或 and 位非
详见这里