char型数为什么表示的是

您所在的位置:网站首页 为什么补码的范围是-128到127 char型数为什么表示的是

char型数为什么表示的是

2024-07-08 07:53| 来源: 网络整理| 查看: 265

这是一个困惑了我几年的问题,它让我对现在的教科书和老师极其不满,从我N年前开始摸电脑时,就几乎在每一本C++教科书上都说,8位有符号的取值范围是-128~+127,为什么不是-127~+127呢,后来的java,int的聚值范围,再32位计算,-2^31 ~ +2^31-1,可是,却从来没有任何一本教科书或一个老师比我解释过这个问题。 原因没有在工作上或者是什么地方直接遇到它,所以我也一直忽略它,但心里总是有一根刺.直到刚才!!!! 就是刚才,无聊之极,在看汇编的书时,又遇到它了,但一如以往,书上直接地,有心地,明显地绕过了这个问题,真是可恶啊.

几经周折,终于把它搞清楚了:

其实,它是计算机底层为了实现数值运算而决定的,涉及非常非常基础的原码,反码,补码知识,一般(99.9999%)都不会用得上. 那0.0001%,估计也就是计算机考试了.

话说: 用2^8来表示无符号整数的话,全世界的理解都是0 - 255了,那么,有符号呢? 用最高位表示符号,0为+,1为-,那么,正常的理解就是 -127 至 +127 了. 这就是原码了,值得一提的是,原码的弱点,有2个0,即+0和-0,还有就是,进行异号相加或同号相减时,比较笨蛋,先要判断2个数的绝对值大小,然后进行加减操作,最后运算结果的符号还要与大的符号相同.

于是乎,反码产生了,原因….略,反正,没过多久,反码就成为了过滤产物,也就是,后来补码出现了.

补码的知识不说述,只说有关+127和-128的. 官方的定义 [-2^(n-1),2(n-1)-1],补码的0没有正负之分.原因呢?没有一本书上有说,这也是我这么火的原因,但通过思考,google,再思考,很快找到答案: 首先,难不免干点白痴般地事情,穷举一下...

正数,原码跟补码一样 +127, 0111 1111 +126, 0111 1110 +125, 0111 1101 +124, 0111 1100 +123, 0111 1011 +122, 0111 1010 … +4, 0000 0100 +3, 0000 0011 +2, 0000 0010 +1, 0000 0001 0, 0000 0000 (无正负之分)

下面是负数了,值,原码,符号位不变其它取反,+1

-1, 1000 0001, 1111 1110, 1111 1111 -2, 1000 0010, 1111 1101, 1111 1110 -3, 1000 0011, 1111 1100, 1111 1101 -4, 1000 0100, 1111 1011, 1111 1100 -5, 1000 0101, 1111 1010, 1111 1011 -6, 1000 0110, 1111 1001, 1111 1010 -7, 1000 0111, 1111 1000, 1111 1001 -8, 1000 1000, 1111 0111, 1111 1000 -9, 1000 1001, 1111 0110, 1111 0111 -10, 1000 1010, 1111 0101, 1111 0110 -11, 1000 1011, 1111 0100, 1111 0101 -12, 1000 1100, 1111 0011, 1111 0100 -13, 1000 1101, 1111 0010, 1111 0011 -14, 1000 1110, 1111 0001, 1111 0010 -15, 1000 1111, 1111 0000, 1111 0001 -16, 1001 0000, 1110 1111, 1111 0000 -17, 1001 0001, 1110 1110, 1110 1111 … -24, 1001 1000, 1110 0111, 1110 1000 … -99, 1110 0011, 1001 1100, 1110 0100 … -124, 1111 1100, 1000 0011, 1000 0100 -125, 1111 1101, 1000 0010, 1000 0011 -126, 1111 1110, 1000 0001, 1000 0010 -127, 1111 1111, 1000 0000, 1000 0001 看出点什么了没有? 如果没有,那么,给个提示, 再继续下去,下一个补码是什么呢?

当然是 -128, 先略过,再略过, 1000 0000

1000 0000,那么,它的原码是什么呢? 从补码求原码的方法跟原码求补码是一样的 先保留符号位其它求反: 1111 1111, 再加1:11000 0000, 超过了8位了 对,用8位数的原码在这里已经无法表示了 关键就在这里,补码 1000 0000 为 -128 是不用怀疑的(上面的穷举), 那么,回到原码处, 它的原码也是 1000 0000(超出的自动丢失), 1000 0000 在原码表示什么呢? -0, 但补码却规定0没有正负之分 转换一下思路,看看计算机里,是怎么运算的: 对于负数,先取绝对值,然后求反,加一 -128 -> 128 -> 1000 0000 -> 0111 1111 -> 1000 0000 现在明确了吧.

所以, 8位有符号的整数取值范围的补码表示 1000 0000 到 0000 0000, 再到 0111 1111 即 -128 到 0, 再到 127 最终 -128 ~ +127

感谢google,感谢被我浏览过又关闭了还忘记了姓名的广大的blog们,CSDN(那上面也有些不错的东西)

补充说明 “一个n位有符号int型数值,其范围为-2^(n-1) ——2^(n-1) -1”,对于这个问题,很多人都是困惑不已。其实,导致此情况的根本原因是“人们解决问题时,习惯以人的思维思考问题,但是,计算机本身确实以机器的思维进行处理的”。在这里,就表现为“计算机对数据的处理其实是以‘补码’的形式,而非日常生活中人们进行数学运算所采用的‘原码’的形式”,但是,人们在对“此数值范围”进行处理的时候,却习惯性的采用了“原码作为机器码”。 在历史上,针对“数值”计算,计算机先后采用过3种机器码——原码、反码和补码。 具体表示如下: 1. 原码 最高位为符号位,其余为对应数值的绝对值的二进制数值表示; 2. 反码 最高位为符号位,正数=原码 负数=符号位+原码对应的其他位数取反; 3. 补码 最高位为符号位,正数=原码 负数=反码+1。 其中,符号位“0为+,1为-”。 因为,计算机为数据类型分配了n位,超过n位的数值会被自动舍弃,那么, 就可以发现,现在计算机系统中采用的补码,克服了“原码中存在+0和-0”的情况,仅表现为一个0,(对于8位数据类型,即为8个0,具体推导见转载内容的穷举,-128计算补码时,产生的9位数据11000 0000–补码1000 0000)。 对应而言,8位有符号位数值的范围就成为了“-2^(8-1) ——2^(8-1) -1”,即“-128——+127”。 问题的关键就在这里了,“计算机为有符号int型数值分配固定的位数n存储数据,当数据位数大于n时,大于n的位数被自动舍弃”。这就是导致数值范围为“-2^(n-1) ——2^(n-1) -1”的原因,从而,也导致了数据范围中“模”概念的产生。 注: 1. 模 “模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。例如,虽然时钟的模=12,但是在时钟的指针并不能真正指向“12点”,“12点”的位置和“0点”是重合的,即12点以0点表示。 换句话说,时钟的范围“0——11”,则模为12。 对应而言,n位无符号数值的计量范围0~2^(n)-1,模=2^(n); n位有符号数值,数值范围-2^(n-1) ——2^(n-1) -1,则模为2^(n-1)。举例说明,8位无符号数值,二进制模为2^8;8位有符号数值,表示的数值范围为0——2^8-1。 2. 补码的运算规则 [X+Y]补 = [X]补 + [Y]补 ;[X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补。

当char c=-129时,就会发生溢出,char类型只有8位,所以最高位(符号位)被舍弃,剩下的8位是原来的9位的补码的低8位。 本来-129的原码为1 1000 0001 补码为1 0111 1111 去掉高位补码为 0111 1111,发现其实这就是+127的补码。 同理-130的原码为1 1000 0010 补码为1 0111 1101去掉高位补码为 0111 1110,发现其实这就是+126的补码。 同理128的原码为0 1000 0000,正数的补码和原码一样,故补码为0 1000 0000,去掉最高位为1000 0000,这是-128的补码

其实就是一个循环 从 -128到0到127再到-128加1和减1都是按照这个循环来的



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3