【转】为什么java中的int类型范围是-2的31次方到2的31次方减一?
在java基础类型中,int类型占四个字节,而每个字节在内存中占8位(8byte),所以可以使用共4X8=32个位数来存储该类型,也就是四个八位的二进制数,所以有了以下说法
在计算机中,它的二级制表示为四个长度为8的二进制数,00000000 00000000 00000000 00000000,不了解的同学可以补一下原码,反码和补码的概念,计算机中的数字是以补码的形式存储的
正数的原码 补码 是相同的,负数不同,负数反码为除符号位的其它位数取反,补码为反码加一,引入反码 补码是为了表示负数来区别开正数,因为二进制没有正负的区别,要区别就得加个标识,就是符号位,按约定,最高位为符号位
首位加粗的0就是是符号位,根据正负要求固定为0或1,为0则代表正数,为1则代表负数
所以实际可用的位数是31位,若为负数,最小表示时,首位为1,其余位数全部为1,则为111111111 11111111 11111111 11111111,其补码为10000000 00000000 00000000 00000001转换成十进制就是-2147483647,即-2^31 + 1,那么看到这里,大家都应该认为int的范围是 -2^31 + 1 到2^31 -1,也就是-2147483647到2147483647,那为什么负数最小能表示到-2147483648 即-2^31呢?问题就出在0上
0的补码,数0的补码表示是唯一的, 例:[+0]补=[+0]反=[+0]原=00000000,[-0]补=11111111+1=00000000
在二进制中,0有两种表方法。+0的原码为0000 0000 0000 0000 0000 0000 0000 0000,-0的原码为1000 0000 0000 0000 0000 0000 0000 0000,因为0只需要一个,而取正0作为0来区别正数和负数
巧合的是-2147483648的补码表示为1000 0000 0000 0000 0000 0000 0000 0000,与-0的原码是一致的,这样,-0便被利用起来,存储-2147483648。
而正数,最大表示时,首位符号位为0,其余位数为1,则为01111111 11111111 11111111 11111111,即2^31-1(2147483647),如果不减一,就是2^31(2147483648),这是你发现2^31二进制补码表示为11111111 11111111 11111111 11111110 ,符号位被占用了而且为1
而符号位为1则代表负数,也就是位数不够用了,若想表示成正数需要多一位表示符号,即 01111111 11111111 11111111 11111110,这样就变成了33位,超出表示范围
所以,java中int类型表示范围是-2^31到2^31-1,大概是21亿左右,注意超出这个范围的数据不要用int类型接受,会有精度问题