java 中 byte 溢出详解,为什么 byte 130 结果为 -126

public class Main {
    public static void main(String[] args) {
        byte b = (byte) 130;
        System.out.println(b); // -126
    }
}

必备知识:

原码、反码、补码

原码:
就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

反码:
正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码:
正数的补码与其原码相同;负数的补码是在其反码的末位加1。

回到正题

在 java 中 byte 130 的 130 默认是 int 类型(十进制),int 类型占用 4 个字节。

将十进制的 130 转化为二进制值为:

00000000 00000000 00000000 10000010

使用 byte 130 意思是强制类型转换,会将 int 类型强制转换为 byte 类型,强制转化过程会进行截取,结果为:

10000010

通过截取后的结果可以看到,符号位(最高位)为 1,说明这是一个负数

在计算机中所有的数据都是以补码的形式出现。所以求出截取后的数据的补码即可。

原码:10000010   
反码:11111101        原码变反码,最高位符号位不变,其他位取反,0变1,1变0
补码:11111110        反码变补码,末位加 1

求得 原码:10000010 的补码为 补码:11111110

最高位为符号位,为 1,代表负数。

剩下的7为数 1111110 转为十进制为:126

加上符号位即为: -126