BugMaker0114头像
关注
为什么瑞天帝是-21亿?_C语言中整型数据类型(有符号或无符号)的取值范围怎么计算 以char(8位)为例封面图

为什么瑞天帝是-21亿?_C语言中整型数据类型(有符号或无符号)的取值范围怎么计算 以char(8位)为例

整型在内存中的存储-原反补

  1. 计算机中的整数有三种2进制表示方法 即原码 反码和补码
  2. 三种表示方法均有符号位和数值位两部分 符号位都是用0表示“正” 用1表示“负”
  3. 正数/无符号数的原、反、补码都相同
  4. 负整数的三种表示方法各不相同:
    原码: 直接将数值按照正负数的形式翻译成二进制就可以得到原码
    反码:原码的符号位不变 其他位依次按位取反就可以得到反码
    补码: 反码+1就得到补码
  5. 对整数来说 正数负数(只要是整数) 内存里存的都是补码

在这里插入图片描述
在这里插入图片描述

对整数来说 内存里存的都是补码

在计算机系统中 数值一律用补码来表示和存储 原因在于:

1.补码与原码相互转换 其运算过程是相同的 不需要额外的硬件电路

在这里插入图片描述
在这里插入图片描述

2.使用补码 可以将符号位和数值域统一处理 同时加法和减法也可以统一处理(CPU只有加法器)
如下图 计算1-1的时候 其实就是1+(-1) 因为CPU只有加法器
如果用原码直接算 结果-2显然错误
在这里插入图片描述
用补码计算就对了 1的原反补都一样 -1算出补码是1111…1111
补码相加的结果给int 最高位那个1被截断了
计算结果就是:000000…00 这个结果也是补码 发现补码最高位是0 则正数 则原反补相同 结果就是0
在刚刚的计算过程中发现 就是直接把补码加起来 并没有区分符号位或者数值位 直接算出结果的补码
在这里插入图片描述

3.补码避免了0和-0的问题 下图以char为例
在这里插入图片描述

4.存的是补码 计算机在计算的时候 用的也是补码

既然存储的是补码 那么在下面讨论char的范围的时候 也就是讨论八个比特位的空间能存多少个数值 也就是八个比特位能表示多少个补码 这些补码对应的数值就是取值范围

无符号unsigned char:[0,255]

无符号 都是有效位 都是正数 原反补相同 直接把排列组合成的二进制读出来 就是范围
100000000-1=11111111
100000000-1=2^8-1=256-1=255=11111111

有符号signed char:[-128,127]

8个bit位 排列组合成补码 放在内存 有256种可能 下图是依次+1
注意1000 0000这个特殊的补码
对于signed char而言 127+3就是补码往下移三个位置对应的值 127+1 = -128 127+2 = -127 127+3 = -126
同理可得short(16位)是-32768~32767
在这里插入图片描述

一些其他的理解/记忆的方法

1.看成一个轮回

在这里插入图片描述

在这里插入图片描述

2.补码的权值

问题:仍然以signed char 也就是8个bit为为例 直接告诉你八位的补码 能否不转换成原码而直接算出它对应的数值?
同理
如果补码是1111 1110 则直接算出-128+64+32+16+8+4+2+0=-2
如果补码是1000 0001 则直接算出-128+0+1=-127
在这里插入图片描述
在这里插入图片描述

再看一个例子 如果补码是1111 1111 数值是?
在这里插入图片描述

3.补码本质是取模的结果

这里mod256是因为都是以char为例 也就是8bit为 也就是2^8
如果是short 那就是mod2^16了
在这里插入图片描述
在这里插入图片描述

其实对于signed char a来说
a=128 和 a=-128
a=255 和 a=-1
他们在内存中发生的事情是一模一样的
在这里插入图片描述

4.从负数到正数 和 正数到负数的两种视角

以前面的3.为例 仍然以char为例
-1在内存里存的补码其实是1111 1111(即255的原码)
-2在内存里存的补码其实是1111 1110(即254的原码)
-128在内存里存的补码其实是1000 0000(即128的原码)
所以如果告知char里存的是负数m 就可以通过m+28=k知道其对应的正数
这个正数k的原码其实就是负数m的补码
如果是short 那就是m+216=k int那就是232

再从正数到负数 把255存进signed char[-128,127] 那肯定是溢出了 实际上得到什么?
这个时候1.那个圆圈就可以派上用场 比如说把255给signed char
想象那个圈上一共是有28=256个排列组合 255相当于转一圈再往后退一个 那就是-1
再比如256 相当于正好转了一圈 那就是0
以此类推 下图a=a+b之后 显然是溢出了 那a实际上是多少?
已知INTMAX=231-1 则a+b=231-1-1+231-1-2=232-5
对于signed int来说 那个圈圈就是有232个排列组合 232-5相当于转了一圈再退五个 也就是-5

在这里插入图片描述
同理如果把234-6赋值给int 也就是转了三圈再退六个 那得到的就是-6
在这里插入图片描述

总结

对于有符号的而言 他们的最小值的补码都是100…00(全为0的情况 假设共有n个0)
有一个很好的记忆方法记住最小值 那就是-2n
比如short就是-215 int就是-231
最大值就是2n-1 比如char就是27-1 int就是231-1
对于无符号而言 就看多少个比特位 比如char就是8个比特位 那么取值范围就是[0,28-1] 这个-1其实就是把28个排列组合里的0给减掉
在这里插入图片描述

既然这样 那么如果是-21亿左右 那大概率是用signed int这一类的数据类型保存的属性值
而且这个-21亿大概率就是最小值了
根据前面的说法 数值应该是-231
找了个视频 发现确实如此
在这里插入图片描述

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_57030936/article/details/158617828

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--