int取值范围的计算方法(Java和C)

为什么Java的int取值范围是**-2^31~ 2^31 -1** (-2147483648 ~ 2147483647)
而不是-2147483647 ~ 2147483647 ?
为什么C的int取值范围是**-2^15 ~ 2^15 -1** (-32768 ~ 32767)
而不是-32767 ~ 32767 ?

以Java为例,Java的int占用空间为4字节,即32Bit,32个二进制位,其中有一位用于存储符号,0表示正,1表示负。(C语言int占空间为2字节,16Bit,同样有一位留给符号)

于是,正数的最大值很容易得到,
0111 1111 1111 1111 1111 1111 1111 1111,共有31位1,
于是得到 2^31 -1 (=2^0 + 2^1 + … + 2^30),即2147483647。
而数字0(+0)的表示方式为:
0000 0000 0000 0000 0000 0000 0000 0000,即32位0。
按照这种方式,不加改进的话,Java中int最小值就是:
1111 1111 1111 1111 1111 1111 1111 1111,即32位1。

也就是-2147483647。

但是,这种方式存在一种浪费情况,也就是0同学一人占了两坑,
1000 0000 0000 0000 0000 0000 0000 0000,
同样也会表示了0(-0),这样0脚踏两只船,很明显有点过分了。

于是为了将后者(也就是-0的表达方式)利用起来,研究者们规定使用“补码”这一方法:
(引用自百度百科 补码

  1. 正整数的补码是其二进制表示,与原码相同,就是保持现状,不做改变;
  2. 求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1。

同一个数字在不同的补码表示形式中是不同的。
比如-15的补码,在8位二进制中是11110001,然而在16位二进制补码表示中,就是1111111111110001。以下都使用8位2进制来表示。
【例】求-5的补码。
-5对应正数5(00000101)→所有位取反(11111010)→加1(11111011)
所以-5的补码是11111011。
【例】数0的补码表示是唯一的。
[+0]补=[+0]反=[+0]原=00000000
[ -0]补=11111111+1=00000000

这样,0只剩下了一种表达方式,腾出了一个坑位,所以,可以比原本的方式多表达一个值。

很幸运,Java中的 -2^31 (-2147483648) 和C语言中的 -2^15 (-32768)抓住了这个来之不易的机会,出现在了历史的舞台之上。

发布了19 篇原创文章 · 获赞 83 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_43838898/article/details/90681768