java中int类型取值范围问题
java中int的类型占4个字节,与操作系统无关,要弄明白int的取值范围问题.
首先,我们来看一下byte的取值范围
byte 大小一个字节.
如:1111 1111 为一个字节
但是整型是分正负的 ,所以在计算机中我们用最高位来表示符号位,0表示正数,1表示负数
byte类型中最大的数 : 0111 1111 表示
2
7
−
1
=
127
2^7-1=127
27−1=127
那么最小的数应该是1111 1111,表示-127了,所以范围应该是-127~127了,但是这和我们常见的byte的取值范围是-128~127并不符合.
这里有一个问题,就是关于0的表示,0的表示有+0和-0之分,但是我们只需要一个来表示0
所以我们就采用+0来表示0.
为了不浪费-0这个数值,我们就将-0来表示-128.
所以取值范围就有了-128~127
看到这里,很多人还是不明白,那我们来看一下-128的二进制表示:
-0的补码对应了-128的补码的后面8位,但是这并不是-128的真正补码,真正的补码已经溢出了.
关于数值溢出问题.
首先我们看下面一段程序.
public class Test {
public static void main(String[] args) {
byte a=127;
byte b = (byte)(a + 1);
System.out.println(b);
}
}
运行结果
127+1
变为了-128,我们来看一下计算机底层都做了什么?
127 的原码:0111 1111加1后为1000 0000,(在计算机中都是补码,有人可能有疑问,为什么127是原码,加1后变为了补码,因为正数的原码和补码是相同的,所以得到的结果就是补码)而补码表示的是128
有人可能疑惑1000 0000 中的1不是符号位吗,为什么能参与运算,事实是:补码是没有符号位的,因为补码就是负数转换为了正数,既然是正数,肯定不需要符号位了.
同理,我们可以退广到int
int的取值范围是
−
2
31
-2^{31}
−231~2
31
^{31}
31-1,即用-0表示最小的数
public class Test {
public static void main(String[] args) {
System.out.println(Integer.MIN_VALUE);//-2147483648=-2^31
}
}
因为-0多表示了一位.和byte中的-128类似
我们可以将数据看成是一个循环圆,这样无论数据如何转换,都将在这个圆内.
public class Test {
public static void main(String[] args) {
//当值大于127时上界溢出,对256取余,剩下的数字就相当于向右走了多少个
int a = 128;
byte b = (byte) a;
System.out.println(b);//-128
//当值小于-128时下界溢出,对256取余,剩下的数字就相当于向左走了多少个
int c =-378;
byte d =(byte)c;
System.out.println(d);//-122
}
}
总结:128%256=128,相当于从0向右走了128,所以输出-128,
378%256=122,想当于从0想左走了122,所以输出-122