首先温习一下的原码、反码、补码计算
原码、反码、补码计算
一、正整数的原码、反码、补码完全一样,即符号位固定为0,数值位相同
二、负整数的符号位固定为1,
由原码变为补码时,规则如下:
1、原码符号位1不变,整数的每一位二进制数位求反,得到反码
2、反码符号位1不变,反码数值位最低位加1,得到补码
由补码变为原码,规则如下:
- 补码符号位1不变,整数的每一位二进制数位求反,得到反码
- 反码符号位1不变,反码数值位最低位加1,得到原码
数据溢出的情况
在计算机中数据的存储都是用补码的编码方式存储的。对一个数的二进制序列它的最高位是符号位。0表示正数,1表示负数。
例如byte类型的变量占8位(以下补码形式表示)
最大为127: 0111 1111
最小为-128 :1000 0000
public static void main(String[] args) {
//计算机中运算时时使用补码进行计算的,展示时是用原码进行展示。
//因此我们先将需要运算的值转化为补码计算,最后再将结果转化回原码输出
byte b = 127;//byte类型只有8位,数值范围为[-128,127]
System.out.println(b);//127,对应补码:0111 1111
b = (byte)(b+1); // 字节类型b+1后数据溢出,运算过程如下
/** 默认转化为int类型相加,int类型占4个字节,转化为int类型高位补0
* 0000 0000 0000 0000 0000 0000 0111 1111
* + 0000 0000 0000 0000 0000 0000 0000 0001
* ————————————————————————————————————————————————
* = 0000 0000 0000 0000 0000 0000 1000 0000
* 然后强转为byte类型,只留最低8位得 1000 0000 即 -128的补码
*/
System.out.println(b); // -128 对应补码:1000 0000
}
试试+127,往后计算数据溢出时的结果 使用相同的思路。
public static void main(String[] args) {
byte b = 127;//byte类型只有8位,数值范围[-128,127]
System.out.println(b);//127,对应补码:0111 1111
b = (byte)(b+127); // 模拟溢出
/** 默认转化为int类型相加,int类型占4个字节
* 0000 0000 0000 0000 0000 0000 0111 1111
* + 0000 0000 0000 0000 0000 0000 0111 1111
* = 0000 0000 0000 0000 0000 0000 1111 1110
* 然后强转为byte类型,留最低8位得 1111 1110 ,求该补码的原码得 1000 0010 转化为十进制即为-2
*/
System.out.println(b); // -2 对应补码:1111 1110
}