概述
学过c语言的都知道,char型变量的取值范围为[-128,127),也就是说,当用一个char型变量来存放数据时,127 + 1 = -128,-128 - 1 = 127。
这个就要涉及到有符号整形变量也就是整数在内存中的存储方式了。也许都听过一个原码反码补码的概念,在计算机中,整形变量存储的方式就是以反码的方式进行存储。
在这里就不介绍反码的发展历程了,我们只需要知道如下概念即可:
- 有符号数在计算机中存储时,最高位为符号位;
- 正数的符号为位0,负数的符号位为1;
- 正数的原码、反码、补码均为其本身;
- 负数的补码计算方法为其原码取绝对值然后按位取反再加一。
以半字节长度存储的±5来举例(1byte=8bit,半字节长度为4bit):
源码 | 取绝对值 | 反码 | 补码 | 描述 | |
5 | 0101 | 0101 | 0101 | 不要想当然认为反码一定会反 | |
-5 | 1101 | 0101 | 1010 | 1011 | 原码先取绝对值再取反+1 |
我们再来尝试一个特殊的整数:0
源码 | 取绝对值 | 反码 | 补码 | 描述 | |
0 | 0000 | 0000 | 0000 | 0视为正数时的表示 | |
-0 | 1000 | 0000 | 1111 | 10000 | 0视为负数时的表示, 由于半字节只有四位, 因此进位的1忽略之后 还是0 |
可以看出补码是解决了0的问题的,这里就用到了进位溢出来保证计算机中0不会出现两种存储方式。回归正题,我们现在再来看看最大值进位溢出的问题,半字节的取值范围为[-8,7)。
7+1,二进制为0111 + 0001 = 1000,按照上述方式逆向解析,1000为负数,因此我们按负数的方式进行逆向解析;先算其绝对值,用补码减一再按位取反:1000 - 1 = 0111,取反得到1000。因此其绝对值为1000也就是8,这个数就是-8。
-8 - 1, -8的原码为1000,反码为0111,补码为1000。因此-8 - 1就是1000 - 0001 = 0111,0111是一个正数,因此其值为7。
再回到char型数就很简单了。char为一个字节也就是8bit,最大值为0111 1111也就是127,最小值为1000 0000也就是减一取反再添负号为-128。
最后,本文仅为自己的理解方式的呈现,若有疑误欢迎批评指正,若有建议欢迎互相交流。
最后
以上就是满意发卡为你收集整理的有符号数的进位溢出问题的全部内容,希望文章能够帮你解决有符号数的进位溢出问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复