免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8451 | 回复: 10
打印 上一主题 下一主题

32位intel的CPU中,int类型为什么最小值为-(2^31) ? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-22 21:06 |只看该作者 |倒序浏览
最近在看《深入理解计算机系统》,里面说,在32位计算机中,对于int类型,最小值是通常为-(2^31)
用二进制补码表示是[1000...0000]
而我觉得最小值
用二进制补码表示应该是[1000...0001]
也就是-(2^31)+1

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

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

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2007-03-23 04:34 |只看该作者
其实二进制补码还有一个更简单的计算方法:

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

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

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

论坛徽章:
0
3 [报告]
发表于 2007-03-23 12:57 |只看该作者
不用想那么复杂,拿 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

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2007-03-23 14:00 |只看该作者
原帖由 mik 于 2007-3-23 12:57 发表于 3楼  
不用想那么复杂,拿 4 位值来举个例子

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

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

我不赞同这种解释。

论坛徽章:
0
5 [报告]
发表于 2007-03-23 14:11 |只看该作者
我学微机原理的时候好像说得是因为+0和-0是一样的,浪费一个编码,就把-0规定成-2^31啦~反正所谓的编码都是人为规定的嘛~就当是反码规定的一部分喽~

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2007-03-23 14:25 |只看该作者
以 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 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-03-23 19:08 |只看该作者
受教了,感谢flw,感谢mik,感谢诸位

论坛徽章:
0
8 [报告]
发表于 2007-03-23 21:27 |只看该作者
原帖由 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 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2007-03-25 19:25 |只看该作者
原帖由 mik 于 2007-3-23 21:27 发表于 8楼  
      1  000
取反  0 111
    +           1
-----------------
          1000     符号位为负,所以是 - 8

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

论坛徽章:
0
10 [报告]
发表于 2007-03-26 13:21 |只看该作者
原帖由 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)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP