🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] > 计算机中是以补码进行计算,原码进行显示 > 正数的反码补码都是其本身 > 负数的反码是原码符号位不变其他取反,补码是反码+1 * 对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 * 计算机存储的就是补码,使用补码进行运算免去了符号位带来的麻烦 * 在计算机内,定点数有3种表示法:**原码、反码和补码** * 原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。 ## 1. 二进制 计算机的存储全是01的二进制,最小单位是byte(8位) **+21,其二进制表示形式是00010101,则其补码同样为00010101** **-21的表示方式** 1. 按照概念其**绝对值为00010101**,各位**取反为11101010**,**再加1**为11101011,即-21的二进制表示形式为11101011 **1. byte为一字节8位,最高位是符号位,即最大值是01111111,因正数的补码是其本身,即此正数为01111111** 2. 10000000是最小负数的补码表示形式,我们把补码计算步骤倒过来就即可。10000000减1得01111111然后取反10000000 因为负数的补码是其绝对值取反,即10000000为最小负数的绝对值,而10000000的十进制表示是128,所以最小负数是-128 ## 1. 八进制 以0开头 ## 2. 十六进制 以0x开头,1-F,一个数字代表四位 f代表15,二进制表示00001111 ## 3. 练习题 ![](https://img.kancloud.cn/3e/c7/3ec784b0c768cc008d72fbb2bf07fbea_672x234.png) ``` 0Xf000000000000000补码为1111000000000000000000000000000000000000000000000000000000000000 0x7FFFFFFFFFFFFFFF补码为0111111111111111111111111111111111111111111111111111111111111111 a-b=a+(-b)= 1111000000000000000000000000000000000000000000000000000000000000+ 1000000000000000000000000000000000000000000000000000000000000001= 10111000000000000000000000000000000000000000000000000000000000001(高位溢出舍去) 则结果为 0111000000000000000000000000000000000000000000000000000000000001= 2^62+2^61+2^60+1 ``` 答案为C ## 1-2 的二进制运算 1的原反补码都相同,都是 0000 0001 -2 的原码是 1000 0010 补码是符号位不变,取反 1111 1101 加1 1111 1110 ``` 0000 0001 + 1111 1110 = 1111 1111 ``` 结果是负数,减一取反,得到原码 1000 0001 即为-1 ## 练习 ~~~java System.out.println((byte) 129); System.out.println((byte) -129); System.out.println("~b2: " + ~10); ~~~ 结果是: ~~~ -127 127 ~b2: -11 ~~~ **计算机中是以补码进行计算** 正数的反码补码都是原码,如: 10 原码: `1010` 反码: `1010` 补码:`1010` 负数 -10 原码 `10000000 00000000 00000000 00001010` 反码(符号位不变,其余位取反) `01111111 11111111 11111111 11110101` 补码(反码+1): `01111111 11111111 11111111 11110110` ### (byte) 129 对于129,二进制为 `00000000 00000000 00000000 10000001` 其补码:`00000000 00000000 00000000 10000001` 由于byte只占1字节即8位,所以,上面截取8位置后如下:`10000001` 此时最高位为1即负数,该二进制减1即是反码 反码:`10000000` 原码:`11111111` 即-127,所以`(byte)129`的结果就是`-127` ### (byte) -129 \-129 二进制为 原码:`10000000 00000000 00000000 10000001` 反码(原码符号位不变,其余取反):`11111111 11111111 11111111 01111110` 补码为(反码+1) : `11111111 11111111 11111111 01111111` 截取8位(低八位)后为:`01111111` 为正数,其原码反码补码均为`01111111`即127 所以`(byte)-129`的结果就是`127` ### ~10 10的二进制为 `00000000 00000000 00000000 00001010` 补码是本身,取反之后为 `11111111 11111111 11111111 11110101` 此时最高位为1,负数,即是负数的补码 该反码(补码-1) `11111111 11111111 11111111 11110100` 对应的原码: `10000000 00000000 00000000 00001011` 即-11 所以`~b2`的结果是`-11` ## 4. 字节运算 ## 4.1 与运算符 与运算符用符号“&”表示,其使用规律如下: 两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。 声明并初始化: int a = 10; int b = 6; 二进制: a = 0000 1010 b = 0000 0110 结算结果: 0000 0010 转化为十进制: 2 ### 4.2 或运算符 或运算符用符号“|”表示,其运算规律如下: 两个位只要有一个为1,那么结果就是1,否则就为0, 声明并初始化: int a = 10; int b = 6; 二进制: a = 0000 1010 b = 0000 0110 结算结果: 0000 1110 转化为十进制: 14 ### 4.3 异或运算符 异或运算符是用符号“^”表示的,其运算规律是: 两个操作数的位中,相同则结果为0,不同则结果为1。 声明并初始化: int a = 10; int b = 6; 二进制: a = 0000 1010 b = 0000 0110 结算结果: 0000 1100 转化为十进制: 10 ### 4.4 非运算, 按位取反 ~5 非运算 补码是: 00000101 补码取反(非): 11111010 补码转反码-1: 11111001 反码转原码(最高位为1,负数):10000110 结果: -6 ## 5.字节位移 ### 5.1 左移 (<< )  右边空出的位用0填补高位左移溢出则舍弃该高位。计算机中常用补码表示数据,注,用补码计算 ![](https://img.kancloud.cn/a7/48/a74885caf41097440086a96e4bac371a_1002x258.png) ### 5.2 右移 (>> )  左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;低位右移溢出则舍弃该位。 ![](https://img.kancloud.cn/be/cf/becf346f728f9f1096d0468afaffb818_855x261.png) ### 5.3 无符号右 、移 (>>> )  无符号右移:正数与右移规则一样,负数的无符号右移,就是相应的补码移位所得,在高位补0即可(右移后,高位0,都是正数,所以得到的就是原码=补码=反码),直接输出 ![](https://img.kancloud.cn/85/ba/85ba8f37ec5ab232dc69542c6531f8b9_782x352.png)