32位intel的CPU中,int类型为什么最小值为-(2^31) ?

发布于 2022-09-28 23:02:23 字数 265 浏览 29 评论 0

最近在看《深入理解计算机系统》,里面说,在32位计算机中,对于int类型,最小值是通常为-(2^31)
用二进制补码表示是[1000...0000]
而我觉得最小值
用二进制补码表示应该是[1000...0001]
也就是-(2^31)+1

按照补码的运算规则,[1000...0000]的值应该也是0吧?
诸位帮我解释一下。

[ 本帖最后由 janusle 于 2007-3-22 21:25 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

南冥有猫 2022-10-05 23:02:23

其实二进制补码还有一个更简单的计算方法:

以 32 bit 的位模式为例. 假设其最高位(即最左边的bit 位, 也即符号位)为 s, 该 32 bit 位模式按无符号二进制数解释表示的十进制数为 b, 则该位模式按照二进制补码解释表示的十进制数即为 b - s * 2^32.

按照这种解释, 应该就很清楚了. 另外, 这种解释在 <<深入理解计算机系统>> 里面也是有说到的.

[ 本帖最后由 MMMIX 于 2007-3-23 04:37 编辑 ]

阳光下的泡沫是彩色的 2022-10-05 23:02:23

不用想那么复杂,拿 4 位值来举个例子

MSB 为符号位,那么,很明显:

正数的取值范围是: 0 000 ~ 0 111, 也就是说最小值是 0 ,   最大值是 7
负数的取值范围是: 1 000 ~ 1 111, 也就是说最小值是 1000(-8), 最大值是 1111 (-1)

1000 为什么是 -8,可以简单算一算

      1  000
取反  0 111
    +           1
-----------------
          1000     符号位为负,所以是 - 8

抚笙 2022-10-05 23:02:23

原帖由 mik 于 2007-3-23 12:57 发表于 3楼  
不用想那么复杂,拿 4 位值来举个例子

MSB 为符号位,那么,很明显:

正数的取值范围是: 0 000 ~ 0 111, 也就是说最小值是 0 ,   最大值是 7
负数的取值范围是: 1 000 ~ 1 111, 也就是说最小值是  ...

我不赞同这种解释。

冷月断魂刀 2022-10-05 23:02:23

我学微机原理的时候好像说得是因为+0和-0是一样的,浪费一个编码,就把-0规定成-2^31啦~反正所谓的编码都是人为规定的嘛~就当是反码规定的一部分喽~

_蜘蛛 2022-10-05 23:02:23

以 4 位为例,我的理解是:
有符号数原码:
0 000 ~ 0 111   +0 ~ +7       前面的 0 表示是正数。
1 000 ~ 1 111   -0  ~ -7        前面的 1 表示是负数。
因为 +0 和 -0 实际上是相等的,也就是说,0 用原码表示的话有两种方式,这样的编码虽然人看起来要好懂一些,但是对于计算机来讲,有三个坏处:
1,违反了唯一性
2,浪费了一个位模式(排列方式)。因为理论上来讲 4 位二进制能表示 2^4 = 16 个不同的数,但是这里只表示了 -7 ~ +7 15 个数。
3,-7 明明是小于 -0 的,但是如果不把最高位当作符号位来看的话,1000 要比 1111 小。
我着重讲一下第三点。因为我们最终的目标是让符号也能够参与运算,也就是说,任何两个有符号数比较大小的时候,我们希望只需要减一下就可以了,因此原码的 1000 和 1111 它的顺序是反的,很不利于运算。
-128 在原码里是无法表示的。

基于以上三个原因,就引进了补码,在介绍补码之前,我先介绍一下反码:
正数的反码就是原码:
0 000 ~ 0 111   +0 ~ +7     反码
负数的反码就是对原码除符号位以外的其余各位进行取反:
1 111 ~ 1 000   -0  ~ -7      反码
这么做的好处是什么呢?好处是,解决了上面三个问题中的第三个问题。
但是另外两个问题还是没有解决。

下面引入的补码,就是为了解决另外两个问题。
补码:
补码的规则是:正数的补码和原码、反码形式相同。
负数的补码,等于反码 + 1,加 1 的时候,符号位也参与运算,溢出位被丢弃,不影响结果。
也就是说:
0 000 ~ 0 111     +0 ~ +7    补码
(1)0 000 ~ 1 001     -0  ~ -7     补码。
注意反码的 -0 也就是 1111 加了 1 之后,符号位产生了进位,溢出了,溢出之后,剩下的部分正好和 +0 一样了。
也就是说,第一个问题也解决了。

第一个问题解决了,那么就剩下第二个问题了,
因为从 -0 到 -7 依次是:
-7:  1 001
-6:  1 010
-5:  1 011
-4:  1 100
-3:  1 101
-2:  1 110
-1:  1 111
-0:  0 000
+1: 0 001
+2: 0 010
...
...
...
也就是说,还剩下 1 000 这个位模式是没用的,
因此就可以用它来表示其它的数。但是到底应该用它来表示 +128 好呢?还是 -128 好呢?
观察上面的序列,你会发现,如果溢出是正常的话,
上面的数列正好是连续的,
而 1 000 比 1 001 还要小 1,因此用来表示 -128 是合理的。加 1 之后正好等于 -127。
因此就用 1 000 来表示 -128 了。

[ 本帖最后由 flw 于 2007-3-23 14:29 编辑 ]

离旧人 2022-10-05 23:02:23

受教了,感谢flw,感谢mik,感谢诸位

三五鸿雁 2022-10-05 23:02:23

原帖由 flw 于 2007-3-23 14:25 发表于 6楼  
以 4 位为例,我的理解是:
有符号数原码:
0 000 ~ 0 111   +0 ~ +7       前面的 0 表示是正数。
1 000 ~ 1 111   -0  ~ -7        前面的 1 表示是负数。
因为 +0 和 -0 实际上是相等的,也就是说,0 用 ...

说得确实精彩。

而 1 000 比 1 001 还要小 1,因此用来表示 -128 是合理的。加 1 之后正好等于 -127。
因此就用 1 000 来表示 -128 了。

计算负数补码的值是很简单的,有一个公式,就以上例 4 位数(1000)为例:

公式为: ( X3 * - 2^(n-1) ) + ( X2 * 2^(n-2) ) + ( X1 * 2^(n-3) ) +  ( X0 * 2^(n-n))
          = (1 * - 2^3)  +  (0 * 2^2)  +  (0 * 2^1)   +  (0 * 2^0)
          = -8 + 0 + 0 + 0
          = -8

每个式子的结果都是可以计算出来的。

所以:
      1000
~       0111
+             1
--------------
            - 8    (由于上述公式所述,就是因为符号位为负,即等于 -8 )

或许大家理解不同,但我偏重于实际。

[ 本帖最后由 mik 于 2007-3-23 21:28 编辑 ]

陈年往事 2022-10-05 23:02:23

原帖由 mik 于 2007-3-23 21:27 发表于 8楼  
      1  000
取反  0 111
    +           1
-----------------
          1000     符号位为负,所以是 - 8

请问在你的这个式子中,第一个 1000 是什么码?0111 是什么码?第二个 1000 又是什么码?

秉烛思 2022-10-05 23:02:23

原帖由 flw 于 2007-3-25 19:25 发表于 9楼  

请问在你的这个式子中,第一个 1000 是什么码?0111 是什么码?第二个 1000 又是什么码?

汗~~ 你还在抓概念

1、
你的精彩理论的论述,我相信在大多数计算机基础的书籍都能找到。关键是灵活掌握,总结适合自己的方法。
况且,你最后给出的答案是错误的。1000 居然等于 -128

我所说的式子是我自己总结出来的一种计算方法,并不能涉及概念性问题。我并没有对式子中的哪个数作“定义性”的描述,只是说“取反”,“+1”。只是计算的方法而已。是方便我计算的。式子中第1个1000是补码,正确来说是“2的补码”,0111是反码,正确来说是“1的补码”,第二个1000我说不出来。

比较正规的计算方法,如我所说的:

  1. 公式为: ( X3 * - 2^(n-1) ) + ( X2 * 2^(n-2) ) + ( X1 * 2^(n-3) ) +  ( X0 * 2^(n-n))
  2.           = (1 * - 2^3)  +  (0 * 2^2)  +  (0 * 2^1)   +  (0 * 2^0)
  3.           = -8 + 0 + 0 + 0
  4.           = -8

复制代码

另一个简单方法,可以:

  1. 1101 = ?
  2. 1101 = 1000 + 100 + 1 = -8 + 4 + 1 = -3

复制代码

2、你所说的人为规定我并不赞同。只有两种情况下才会有 +0 以及 -0 存在,就是浮点数
对单精度数来说:

  1. 0x00000000 = +0.0
  2. 0x80000000 = -0.0

复制代码这种情况是并存的,并不矛盾。

就拿 8 位数来说:
10000000  = -128,是通常计算出来的,不是“用来表示-128”这种概念

对符号数来说:10000000 就是个模值。-1 回卷0111 1111(127)  +1 进值 10000001 (-127)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文