文章目录
一、整数在计算机中的存储形式
数字 | 计算机中的存储形式 |
---|---|
− 2 31 -2^{31} −231 | 1000 0000 0000 0000 0000 0000 0000 0000 |
− 2 31 + 1 -2^{31} + 1 −231+1 | 1000 0000 0000 0000 0000 0000 0000 0001 |
− 2 31 + 2 -2^{31} + 2 −231+2 | 1000 0000 0000 0000 0000 0000 0000 0010 |
− 2 31 + 3 -2^{31} + 3 −231+3 | 1000 0000 0000 0000 0000 0000 0000 0011 |
− 2 31 + 4 -2^{31} + 4 −231+4 | 1000 0000 0000 0000 0000 0000 0000 0100 |
− 2 31 + 5 -2^{31} + 5 −231+5 | 1000 0000 0000 0000 0000 0000 0000 0101 |
− 2 31 + 6 -2^{31} + 6 −231+6 | 1000 0000 0000 0000 0000 0000 0000 0110 |
− 2 31 + 7 -2^{31} + 7 −231+7 | 1000 0000 0000 0000 0000 0000 0000 0111 |
− 2 31 + 8 -2^{31} + 8 −231+8 | 1000 0000 0000 0000 0000 0000 0000 1000 |
… | … |
− 8 -8 −8 | 1111 1111 1111 1111 1111 1111 1111 1000 |
− 7 -7 −7 | 1111 1111 1111 1111 1111 1111 1111 1001 |
− 6 -6 −6 | 1111 1111 1111 1111 1111 1111 1111 1010 |
− 5 -5 −5 | 1111 1111 1111 1111 1111 1111 1111 1011 |
− 4 -4 −4 | 1111 1111 1111 1111 1111 1111 1111 1100 |
− 3 -3 −3 | 1111 1111 1111 1111 1111 1111 1111 1101 |
− 2 -2 −2 | 1111 1111 1111 1111 1111 1111 1111 1110 |
− 1 -1 −1 | 1111 1111 1111 1111 1111 1111 1111 1111 |
0 0 0 | 0000 0000 0000 0000 0000 0000 0000 0000 |
1 1 1 | 0000 0000 0000 0000 0000 0000 0000 0001 |
2 2 2 | 0000 0000 0000 0000 0000 0000 0000 0010 |
3 3 3 | 0000 0000 0000 0000 0000 0000 0000 0011 |
4 4 4 | 0000 0000 0000 0000 0000 0000 0000 0100 |
5 5 5 | 0000 0000 0000 0000 0000 0000 0000 0101 |
6 6 6 | 0000 0000 0000 0000 0000 0000 0000 0110 |
7 7 7 | 0000 0000 0000 0000 0000 0000 0000 0111 |
8 8 8 | 0000 0000 0000 0000 0000 0000 0000 1000 |
… | … |
2 31 − 8 2^{31} - 8 231−8 | 0111 1111 1111 1111 1111 1111 1111 1000 |
2 31 − 7 2^{31} - 7 231−7 | 0111 1111 1111 1111 1111 1111 1111 1001 |
2 31 − 6 2^{31} - 6 231−6 | 0111 1111 1111 1111 1111 1111 1111 1010 |
2 31 − 5 2^{31} - 5 231−5 | 0111 1111 1111 1111 1111 1111 1111 1011 |
2 31 − 4 2^{31} - 4 231−4 | 0111 1111 1111 1111 1111 1111 1111 1100 |
2 31 − 3 2^{31} - 3 231−3 | 0111 1111 1111 1111 1111 1111 1111 1101 |
2 31 − 2 2^{31} - 2 231−2 | 0111 1111 1111 1111 1111 1111 1111 1110 |
2 31 − 1 2^{31} - 1 231−1 | 0111 1111 1111 1111 1111 1111 1111 1111 |
二、计算机存储数字的原理
2.1.原码
int型数据在计算机中以二进制存储,一个int型数据占4个字节,一个字节占8位,一共32位。
(1)第一位是标志位,标志位为0表示正数,标志位为1表示负数。
(2)剩余的31位是用来表示数字部分的
2.2.补码
在计算机中,数字以补码存储。正数的补码是其本身,负数的补码是除标志位外,其他位按位取反再加一。
2.3.补码的特性
1、一个负整数(或原码)与其补数(或补码)相加,和为模。
2、对一个整数的补码再求补码,等于该整数自身。
3、补码的正零与负零表示方法相同。
三、两个例子理解补码的计算方式
3.1、第一个例子:7的存储形式
3.1.1.原码
(1)7是正数,所以标志位为0
(2)剩余的31位表示数字部分:000 0000 0000 0000 0000 0000 0000 0111
所以7的原码是:
0000 0000 0000 0000 0000 0000 0000 0111
3.1.2.补码
正数的补码与原码一样,所以7在计算机中的存储形式为:
0000 0000 0000 0000 0000 0000 0000 0111
3.2、第二个例子:-7的存储形式
3.2.1.原码
(1)-7是负数,所以标志位为1
(2)剩余的31位表示数字部分:000 0000 0000 0000 0000 0000 0000 0111
所以-7的原码是:
1000 0000 0000 0000 0000 0000 0000 0111
3.2.2.补码
负数的补码是除标志位外,其他位按位取反再加一。所以-7在计算机中的存储形式为:
1111 1111 1111 1111 1111 1111 1111 1001
四、为什么int型数据取值范围是 [ − 2 31 , 2 31 − 1 ] [-2^{31}, 2^{31}-1] [−231,231−1]
由原理可知,计算机存储数字时,第一位是标志位,只有31位用来存储数字的值。所以最大表示的正数为0111 1111 1111 1111 1111 1111 1111 1111,即:
2
31
−
1
2^{31}-1
231−1
对于负数,当存储数字的31位均为1时,值为
2
31
−
1
2^{31}-1
231−1,加上标志位1,此时的负数原码为:
1111 1111 1111 1111 1111 1111 1111 1111
对应的补码为:
1000 0000 0000 0000 0000 0000 0000 0001
用类似的表示方法可以表示出
[
−
2
31
+
1
,
2
31
−
1
]
[-2^{31}+1, 2^{31}-1]
[−231+1,231−1]中的数,但是如果这么计算的话,1000 0000 0000 0000 0000 0000 0000 0000 这个数字就被浪费了。对于计算机宝贵的内存,浪费是绝对不允许的,所以1000 0000 0000 0000 0000 0000 0000 0000这个数字就被规定为表示
−
2
31
-2^{31}
−231。所以int型数据取值范围是
[
−
2
31
,
2
31
−
1
]
[-2^{31}, 2^{31}-1]
[−231,231−1]
五、为什么要用补码
5.1.类比:时钟使用补码计算加减
例如:时钟的计量范围是0~23,所以时间的模等于24。假设当前时针指向17点,而准确时间是9点,调整时间可有以下两种方法:
1.倒拨8小时,即:17 - 8 = 9;
2.顺拨16小时:17 + 16 = 33 ; 33 % 24 = 9
此例中, 16 就是 -8 在 24 进制中的补码表示。用 16 表示 -8 的好处是将减法转为了加法。
5.2.计算机使用补码计算加减
如果正数和负数都用原码表示,计算机计算加减法需要做不同的处理。而如果使用补码表示,计算机计算加减法时统一使用加法计算即可,减轻了计算机的负担。
5.2.1.第一个例子:计算 9 + 5
9 的补码表示为:
0000 0000 0000 0000 0000 0000 0000 1001
5 的补码表示为:
0000 0000 0000 0000 0000 0000 0000 0101
两个补码相加,并去掉32位以外的数(本例结果没有32位以外的数):
0000 0000 0000 0000 0000 0000 0000 1110
即得到了结果 14
5.2.2.第二个例子:计算 9 - 5
9 的补码表示为:
0000 0000 0000 0000 0000 0000 0000 1001
-5 的补码表示为:
1111 1111 1111 1111 1111 1111 1111 1011
两个补码相加,并去掉32位以外的数:
0000 0000 0000 0000 0000 0000 0000 0100
即得到了结果 4
5.2.3.第三个例子:计算 − 2 31 + 1 -2^{31}+1 −231+1
上文说道,为了不浪费内存,1000 0000 0000 0000 0000 0000 0000 0000这个数字被规定为表示
−
2
31
-2^{31}
−231,事实上这个数字表示
−
2
31
-2^{31}
−231并不是凭空规定的,它也符合补码的加减规则。
−
2
31
-2^{31}
−231 的补码表示为:
1000 0000 0000 0000 0000 0000 0000 0000
1 的补码表示为:
0000 0000 0000 0000 0000 0000 0000 0001
两个补码相加,并去掉32位以外的数(本例结果没有32位以外的数):
1000 0000 0000 0000 0000 0000 0000 0001
即得到了结果
−
2
31
+
1
-2^{31}+1
−231+1
六、拓展
由原理可推导出:
Java中short
型整数占16位,取值范围:
[
−
2
15
,
2
15
−
1
]
[-2^{15}, 2^{15}-1]
[−215,215−1]
long
型整数占64位,取值范围:
[
−
2
63
,
2
63
−
1
]
[-2^{63}, 2^{63}-1]
[−263,263−1]
附一:位、字节、字符的区别
- 位(bit):计算机内部,数据储存的最小单位。如:00110011 是一个八位二进制数
- 字节(byte):计算机中数据处理的基本单位。通常用大写的 B 表示,1 byte = 8 bit
- 字符:计算机中使用的字母、数字、字、符号。
在 ASCII 编码中:
1 个英文字母占 1 个字节
1 个汉字占 2 个字节
1 个 ASCII 码占 1 个字节
在 UTF-8 编码中:
1 个英文字符、英文标点占 1 个字节
1 个中文字符、中文标点占 3 个字节
在 Unicode 编码中:
1 个英文字符、英文标点占 2 个字节
1 个中文字符、中文标点占 2 个字节
附二:Java 中八种基本数据类型占用空间
- boolean:1 字节
- byte:1 字节
- short:2 字节
- char:2 字节
- int:4 字节
- float:4 字节
- long:8 字节
- double:8 字节
注:
- 不带后缀的整数默认为 int,不带后缀的小数默认为 double
- 超出 int 取值范围的整数必须添加后缀
L
或者l
,表示 long 类型。建议使用L
,因为l
容易与数字 1 混淆 - 带有
F
或f
后缀的数都属于 float 类型,带有D
或d
后缀的数都视为 double 类型 - 编译器会在编译期检查八种基本类型的取值范围,如果超出了范围会报错
- int 值可以赋值给所有数值类型;
- long 值可以赋值给 long、float、double类型,为什么 long 值占 8 个字节可以赋值给只占 4 个字节的 float 呢?这是因为赋值时会自动舍弃精度并转换为科学计数法。如:Long.MAX_VALUE:
9223372036854775807
,赋值给 float,变为:9.223372E18
- float 值可以赋值给 float、double 类型
- double 值只能赋值给 double 类型