问题引入
说明
以下程序是java程序
byte是存储整型,占一个字节(8位)的存储空间
结果
- 127+1=-128
- -128-1=127
这是为什么呢?
这就说到整数在计算机中是怎么存储的?
存储整数
以下内容取自《计算机导论》的3.2.1存储整数
1.无符号表示法
无符号整数是只包括零和正数的非负整数。它的范围介于0到无穷大之间。然而,由于计算机不可能表示这个范围的所有整数,通常计算机都定义了一个常量,称为最大无符号整数,它的值是(2"-1)。这里n就是计算机中分配用于表示无符号整数的二进制位数。
存储无符号整数
输人设备使用以下步骤存储无符号整数:
1)首先将整数变成二进制数。
2)如果二进制位数不足n位,则在二进制数的左边补0,使它的总位数为n位。
如果位数大于n,该整数无法存储。这会导致溢出情况发生,我们后面要讨论。
例题3-1 将7存储到8位存储单元中,使用无符号表示法。
例题3-2 将258存储到16位存储单元中。
溢出
因为大小(即存储单元的位的数量)的限制,可以表达的整数范围是有限的。
在n位存储单元中,我们可以存储的无符号整数仅为0到2”-1之间。
图3-5显示了如果存储大于24-1=15的整数到仅为4位的内存中所发生的情况。
例如,保存整数11在存储单元中,又试图再加上9,就会发生这种称为溢出的情况。
表示十进制数20的最小位数是5位,即20=(10100)2, 所以计算机丢掉最左边的位,并保留最右边的4位(0100)2。
当人们看到新的整数显示为4而不是20时很惊讶。 图3-5显示了为什么会发生这种情况。
无符号整数的应用
无符号整数表示法可以提高存储的效率,因为不必存储整数的符号。这就意味着所有
配的位单元都可以用来存储数字。只要用不到负整数,都可以用无符号整数表示法。具体情
况如下
- 计数:当我们计数时,不需要负数。可以从1(有时0)开始增长。
- 寻址:有些计算机语言在一个存储单元中存储另一个存储单元的地址。地址都是从0
(存储器的第一个字节)开始到整个存储器的总字节数的正数,在这里同样也不需要
用到负数。因此无符号整数可以轻松地完成这个工作。 - 存储其他数据类型:我们后面将谈到的其他数据类型(文本、图像、音频和视频)是
以位模式存储的,可以翻译为无符号整数。
2.符号加绝对值表示法
尽管符号加绝对值表示法格式在存储整数中并不常用,但该格式用于在计算机中存储 部分实数、正如下一节所述。因此,我们在这里简要讨论该格式。在这种方法中,用于无符号整数的有效范围(0到2”-1)被分成两个相等的子范围。前半个表示正整数,后半个表示负整数。
例如,而n为4,该范围是0000到1111。这个范围被分为两半:0000到0111以及
1000到1101(图3-6)。这种位模式赋值为正的和负的整数。注意,负数出现在正数的右边,
与常规的关于正负数的思维相反。还要注意该系统中有两个0:正0(0000)和负0(1000),
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
0 1 2 3 4 5 6 7 -0 -1 -2 -3 -4 -5 -6 -7
图3-6符号加绝对值的表示法
用符号加绝对值格式存储 一个整数,需要用1个二进制位表示符号(0表示正,1表示负)。这就意味着在一个8位存储单元中,可以仅用7位表示数字的绝对值(不带符号)。因此,最大的正数值仅是无符号最大数的一半。在n位单元可在储的数字范围是-(2n-1-1)至 +(2n-1-1),n位单元中最左位分配用于存储符号(0表示正、1表示负).
在符号加绝对值表示法中,最左位用于定义整数的符号。0表示正整数,1表示负整数
在符号加绝对值表示法中,有两个0:+0(00…00)和-0(10…00)
符号加绝对值的表示法的应用
符号加绝对值表示法不用于存储整数,而用于存储部分实数。 另外,符号加绝对值表示法通常用于采样模拟信号,例如,音频。
3.二进制补码表示法
几乎所有的计算机都使用二进制补码表示法来存储位于n位存储单元中的有符号整数 这一方法中,无符号整数的有效范围(0到2”-1)被分为两个相等的子范围。第一个子范围用来表示非负整数【0到2n-1-1】,第一个子范围用来表示负整数【-2n-1到0)。
例如,如果n为是4,该范围是0000 到1111。这个范围分为两半:0000到0111以及1000到1111。这两半按照左负右正的常规互相交换。赋值给负和非负(零和正)整数的位模式如图3-8所示。
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 11001 1011 1101 1111
1000 1001 1010 1011 1100 1101 1110 1111 0000 0001 0010 0011 0100 0101 0110 0111
-8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
图3-8 二进制补码表示法
尽管整数的符号影响二进制整数存储时的每一位,但是首位(最左位)决定符号。如果最左位是0,该整数非负;如果最左位是1,该整数是负数。
在二进制补码表示法中,最左位决定符号。如果它是0,该整数为正;如果是1,该整数为负。
两种运算
在深入讨论这种表示法之前,我们需要介绍两种运算。第一种称反码或取一个整数的反码。
该运算可以应用于任何整数,无论是正的还是负的。该运算简单反转各个位,即把0位变为1位,把1位变为0位。
例3-8下面显示我们如何取整数00110110的反码
原来的模式 0 0 1 1 0 1 1 0
进行反码运算 1 1 0 0 1 0 0 1
例3-9下面显示我们如果进行2次反码运算,就可以得到原先的整数。
原来的模式 0 0 1 1 0 1 1 0
进行1次反码运算 1 1 0 0 1 0 0 1
进行2次反码运算 0 0 1 1 0 1 1 0
第二种运算称为二进制中的补码或取一个数数的补码,该运算分为两步:首先,从右边复制位,直到有1被复制;接着,反转其余的位。
例3-10下面显示我们如何取整数00110100的补码
原来的模式 0 0 1 1 0 1 0 0
进行1次补码运算 1 1 0 0 1 1 0 0
例3-11 下面显示我们如果进行2次补码运算,就可以得到原先的整数。
原来的模式 0 0 1 1 0 1 0 0
进行1改补码运算 1 1 0 0 1 1 0 0
进行2改补码运算 0 0 1 1 0 1 0 0
另一种将整数进行补码运算的方法是先对它进行1次反码运算再加上1得到结果(参见第4章的二进制加法)
以二进制补码格式存储整数
以二进制补码格式存储整数,计算机遵循以下步骤:
- 将整数变成n位的二进制数
- 如果整数是正数或零,以其原样存储;如果是负数,计算机取其补码存储
以二进制补码格式还原整数
从二进制补码格式还原整数,计算机遵循以下步骤;
- 如果最左位是1,计算机取其补码。如果最左位是0、计算机不进行操作
- 计算机将该整数转换为十进制
例3-12 用二进制补码表示法将整数28存储在8位存储单元中
解 该整数是正数(无符号意味是正的),因此在把该整数从十进制转换成二进制后不再需要其他操作。注意,3个多余的零加到该整数的左边使其成为8位。
把28变为8位的二进制 0 0 0 1 1 1 0 0
例3-13 用二进制补码表示法将整数-28存储在8位存储单元中
解 该整数是负数,因此在转换成二进制后计算机对其进行二进制补码运算
把28变为8位的二进制 0 0 0 1 1 1 0 0
进行补码运算 1 1 1 0 0 1 0 0
例3-14 将用二进制补码表示法存储在8位存储单元中的00001101还原成整数
解 最左位是0.因此符号为正。该整数需要转换为十进制并加上符号即可。
最左位是0,符号为正 0 0 0 0 1 1 0 1
整数转换为十进制 13
加上符号(可选) +13
例3-15 将用二进制补码表示法存储在8位存储单元中的11100110还原成整数
解 最左位是1,因此符号为负。在整数转换为十进制前进行补码运算。
最左位是1,符号为负 1 1 1 0 0 1 1 0
进行补码运算 0 0 0 1 1 0 1 0
整数转换为十进制 26
加上符号 -26
二进制补码表示法很有趣的一点是该表示法仅有 一个0,而符号加绝对值表示法则有 个0(+0和-0)。
二进制补码表示法仅有一个0
二进制补码表示法的溢出
补码运算的规则为:
① [X]补+[Y]补=[X+Y]补
两数补码的和等于两数和的补码
② [X]补-[Y]补=[X]补+[-Y]补=[X-Y]补
两数补码的差等于两数差的补码
计算机中带符号数用补码表示时有如下优点:
① 可以将减法运算变为加法运算,因此可使用同一个运算器实现加法和减法运算,简化了电路。
② 无符号数和带符号数的加法运算可以用同一个加法器实现,结果都是正确的。:
3种系统的比较
回到问题
127+1=-128
-128-1=127
byte是存储整型,占一个字节(8位)的存储空间
8位二进制补码可以表示的范围为【-28-1到28-1-1】,即 -128到127
参照 二进制补码表示法的溢出
所以127+1会造成正溢出,将会=-128
所以-128-1会造成负溢出,将会=127
参照补码运算的规则
补码1 0 0 0 0 0 0 0等于-128
原码 补码
127 0 1 1 1 1 1 1 1
+ 1 0 0 0 0 0 0 0 1
= -128 1 0 0 0 0 0 0 0
最高位的1被截掉,只留低八位
补码0 1 1 1 1 1 1 1等于127
原码 补码
-128 1 0 0 0 0 0 0 0
+ -1 1 1 1 1 1 1 1 1
= 127 1 0 1 1 1 1 1 1 1