计算机整数编码系统
二进制
我们都知道现代计算机存储和处理的信息都是以二进制的形式来表示的,在计算机中那些能看到的跟不能看到的东西都是由一个一个二进制位来表示的,而每一个位(bit)中储存的值只能是0和1。
因为在数字电路层面上用高低电平来表示数据有很大的便利性,因模拟电路极容易受到噪声干扰,所以波形也会有较大的变化。而数字电路因为只有高低电平,抗干扰能力强,所以也被越来越广泛的应用到各种电子设备上。所以说为什么计算机内部的数据结构是以二进制的方式组织就是这个原因。
计算机中最小的储存单位是位(bit)但是一个位往往作用不大,想要表示有实际意义,有实际作用的数就需要用多个位组合在一起来扩大数的表示范围,在计算机中一般用8个位组成一个字节,一个字节就是计算机中的最小的寻址单位,也就是内存中最小的储存空间分块是8个位,即一个字节。
无符号整数的编码
先来看看无符号整数的编码,因为无符号整数编码比较符合人们的直观感觉,所以一般要理解无符号数字的编码并不会有什么问题。无符号数的编码可以用相应的十进制数一直除以2,然后把余数放到低位(数最右边就是低位)就可以得到相应的2进制数了。而这个二进制数也是计算机里面的编码方式。
上面公式D是十进制数, xi 为第i位二进制数,所以说二进制转换成十进制只要把二进制每一位乘以相应的位权再相加就是相应的十进制数了。
下面我们来考虑无符号编码的表示范围,假设该二进制数有 w 位,则该二进制数总共可以表示
从上两式中也可以看出无符号数的一个很重要的性质,即介于 [0,2w−1] 之间的数都有唯一对应的一个二进制 w 位的二进制数,用数学语言来说就是二进制跟十进制的转换函数是一个双射。
无符号编码的值大小
下面是在C\C++中无符号基本数据类型的最小值跟最大值(64位机器)
数据类型 | 最小值 | 最大值 |
---|---|---|
unsigned char | 0 | 255 |
unsigned short | 0 | 65 535 |
unsigned int | 0 | 4 294 967 295 |
unsigned long | 0 | 18 446 744 073 709 551 615 |
(因为机器不同和编译环境不同上面这些值要根据机器和编译环境来实际考虑,上表是针对一般64位CPU和系统)。
有符号整数的编码(补码)
从上一节也可以看出来计算机无符号整数的编码是多么的自然,直观,很容易就能被理解接受。但是无符号的编码毕竟只能编码无符号数,但是日常生活生产里面必然会有很大一部分要用到负数的,那么负数在计算机里面是怎样被编码的出来的呢?
原码,反码,和补码
原码:原码表示是最简单的,第一位为符号位其余位为相应的数值即10000001为-1。
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码:也是第一位为符号位,符号位1为负数,0为正数,这跟原码,反码一样。
原码中因为不能在数学上直接参与运算,容易出错。要计算的话必须符号位与其他位分开储存计算,所以这无疑增加了系统开销,所以原码和反码在现代计算机中很少采用这两种编码方案。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
我们用函数
其中 x⃗ 为二进制为 w 位的向量形式,其中的分量只能是0和1。上式可以看到最高位为符号位,最高位
下面来举几个例子来看看补码如何运作
下面我们来考虑 w 位补码所能表示的范围,上面的式子所能表示的最小值是最高位为1,其他位均为零的时候即
补码的值的大小
下面是在C\C++中无符号基本数据类型的最小值跟最大值(64位机器)
数据类型 | 最小值 | 最大值 |
---|---|---|
char | -128 | 127 |
short | -32 768 | 32 767 |
int | -2 147 483 648 | 2 147 483 647 |
long | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 |
喜欢我们的内容,可以微信搜索公众号
科学技术工作室或扫下面的二维码关注我们