1.表示范围:
假设二进制机器字长是n+1位,且为整数(因为有一位是符号位,这样表示更好理解)
原码表示的范围: −(-1)≤ x ≤
-1
反码表示的范围: −(-1)≤ x ≤
-1
补码表示的范围: −≤ x ≤
-1
移码表示的范围: −≤ x ≤
-1
移码的符号位中0表示负数,1表示正数,简单来说,原码的补码数值位不变,符号位取反就是移码。
对于8位寄存器:
原码表示范围为 -127-127,即1111 1111~0111 1111
反码表示范围为 -127-127,即1000 0000~0111 1111
补码表示范围为 -128-127,即1000 0000~0111 1111
移码表示范围为 -128-127,即0000 0000~1111 1111
2.数据溢出:
数据溢出原理:数据范围的表示是一个环状结构,如果数据增长到最大值,则数据从最小值方向开始依次递增,如果数据减到最小值,则数据从最大值方向开始依次递减。
方法总结:
①
如果超过该范围的最大值,正值,那么使用该数值减去 (n是多少bit 1字节=8bit 2字节=16bit),例如200,超过了127,则200-
=-56 在该区间内,输出-56
例如500,超过了127,则500-256=244,不在该区间,继续减去256,244-256=-12,在该区间内,输出-12
②
如果超过该范围的最小值,负值,那么使用该数值加上 (n是多少bit 1字节=8bit 2字节=16bit),例如-200,超过了最小值,则-200+
=56 在该区间内,输出56
例如-600,超过了-127,则-600+256=-344,不在该区间,继续+256,-344+256=-88,在该区间内,输出-88
3.例题分析:
例题1(期末考试题):
若寄存器内容为00000000,若它等于-128,则为( C )
A. 原码
B. 补码
C. 移码
D. 反码
解题:
符号位为0,所以ABD即原码、反码、补码为正数,正数的原码、反码、补码相同,转换为十进制为0;
移码的符号位中0表示负数,00000000即为-128,由于-128超出8位寄存器原码和反码的范围,所以计算-128的时候不能使用符号位不变数值位取反加一,需要特殊记。
例题2(某公司笔试题):
下列代码的运行结果(B)
short i = 65537;
int j = i + 1;
printf(“i = % d, j = % d\n”, i, j);
A i=65537,j=65538
B i=1,j=2.
C i=-1,j=0
D i=1,j=65538
解题:
short为16位,表示范围为(补码):−≤ x ≤
-1
int为32位,表示范围为(补码):−≤ x ≤
-1
i = 65537,超出最大表示范围,使用上述我讲的方法计算,则 65537-=1;
根据程序自上而下执行,i = 1, j = i + 1 = 2,所以选B。
例题3(期末考试题):
设机器数采用补码表示(含1位符号位),若寄存器内容为9BH,则对应的十进制数为( D )
A. -97
B. -101
C. -27
D. 155
解题:
方法一:9BH转化为十进制为155,因为8位寄存器补码表示范围为 -128-127,溢出,使用上述我讲的方法计算,则155 - = -101;
方法二:9BH转化为二进制为10011011,补码10011011转为原码为11100101,转换为十进制为-101;
4.总结感悟:
这篇文章是我在一次面试后写的,当时面试官问我关于原码,反码,补码,移码的认知,我直接就懵了,面试居然还会问这种问题,我就给面试官简单讲了一下原码,反码,补码,移码的含义和转换,显然面试官不是想听我给他讲定义和转换的,然后面试官下一个问题就是关于数据溢出的,后面又深度的问了我很多关于数据溢出的问题,以及发生数据溢出的解决方案(当时面试官给我描述了一个数据溢出的场景),让我现场敲代码给出解决方案,我当时的做法是换了一个更大的数据储存类型,还加了边界检查以及异常抛出,后面又从数据溢出引出关于内存管理的很多问题,都是给我一个场景,让我现场手撕代码给出解决方案,不过还好,都是一些基础,有一定的代码量和知识储备没有太大问题。
最后给大家一个建议,不管平时学习还是办公,对于一个知识领域,一定要深度学习其底层的原理,不要只停留在表层,仅仅会用是完全不够的。
如果觉得我的这篇文章对你有帮助,请点赞收藏加关注,谢谢大家。