单位换算
1 Byte(B) = 8 bit
1 Kilo Byte(KB) = 1024B
1 Mega Byte(MB) = 1024 KB
1 Giga Byte (GB)= 1024 MB
1 Tera Byte(TB)= 1024 GB
1 Peta Byte(PB) = 1024 TB
从上可以了解计算机最小的存储单位是bit,即一位二进制数(0 或 1),8个二进制位为一个字节(B),这个字节也是最常用的单位,对应我们Java的:
最常用的int 需要4个字节,4个8位,也就是32位 ,即 00000000 00000000 00000000 00000000
我们来详细看下,每个位可以代表几个数字
1个位能表示多少东西: 只有2种情况(0,1),最小0 最大1,推导出 2的1次方 = 2
2个位能表示多少东西: 有4种情况(00,01,10,11),最小00 最大11,推导出 2的2次方 = 4
3个位能表示多少东西: 有8种情况(000,001,010,011,100,101,110,111),最小000 最大111,推导出 2的3次方 = 8
...
8个位能表示多少东西:最小:00000000 最大:11111111,用上面推导的算法2的8次方 = 256 这就是8位 也叫一个字节
关键点来了,一个字节的范围是多少?
a.如果没有正负之分,那可以表示 0~255 共256个数字,范围就是最小值是0,最大值是255(计算机有正负区分,所以这个值是错的)
b.如果有正负之分,那可以表示 -128 ~ 127 (规定) 也是256个数,那为啥是这样,重点来了,仔细看:
计算机用最高位,1代表负数,0代表正数,以8位来表示就是 0xxxxxxxx 的第一个0代表正数, 1xxxxxxxx的第一个1代表负数 ,那么8位的第一个位(最高位)就不能算,也就是说只有7位, 即2^7=128 个数字,一共正负各128种状态,如果不采用特殊处理,这时候0占用2个编码(10000000和00000000),数据表示范围为-127到-0及+0到127,这样总体上一个字节只有255种状态,因为其中0具有正0和负0之分,这不符合数学意义也浪费一个编码(早期硬件很昂贵,一位或者一个编码的浪费都是不可饶恕的)。所以计算机规定,如果是正0,也就是说遇到00000000这个编码(正0)就算它为0,如果遇到10000000(负0)这个编码会特殊处理一下,用下面的算法处理
遇到10000000(负0)这个编码
先取反,得到值为:01111111
再加1,得到值为 :10000000
此时10000000的最高位还是1代表负数的定义,同时原先表示负0的编码被利用起来表示-128
现在能理解为啥一个字节(8位)的范围为 -128 ~ 127,即范围就是最小值是-128,最大值是127
接下来 继续:
9位 = 2^ 9=512
10位 = 2^ 10 =1024
..... 以此类推直到第32位,也就是int的存储(4个字节),我们知道int的取值范围是-2147483648 ~ 2147483647 ,那为啥是这个范围呢?结合上面8位的取值范围-128 ~ 127 的原理,可以推倒其32位范围的原理
首先公式还是一样,2^32 = 4294967296,总共32位可以代表有这么多个数字,因为知道了计算机是分正负数的,所以4294967296 / 2 = 2147483648 ,也就是说从 -2147483647 ~ -0 和 +0 ~ 2147483647 这么个范围了,但是上面说了-0是浪费的,因为计算机是以补码的形式来存储数字的,
不管-0 (对应的码是1000 0000 0000 0000),
还是+0(对应的码 0000 0000 0000 0000),
补码都是0000 0000 0000 0000,这就造成了没有任何一个数的补码后值是1000 0000 0000 0000,所以就可以把这个补码用来存储一个数(不能浪费资源),就规定用它来存储一个数-2147483648