当前位置: 代码迷 >> C语言 >> 请教 数据类型 补码方面..
  详细解决方案

请教 数据类型 补码方面..

热度:1066   发布时间:2008-06-27 01:10:49.0
请教 数据类型 补码方面..
我是一只刚刚入门的小小菜鸟..  


因为基础较差(都是因为以前上的破电脑学校)

最近刚学到数据类型..

感觉有一些东西似懂非懂. 学得有一点吃力..

就是关于 补码 进制 之类的 汇编基础吧 不太懂..

  请教大虾门, 有什么办法可以补一补这方面的知识..

    教程或者 有什么书.. 越易懂越好..
搜索更多相关的解决方案: 数据类型  学校  

----------------解决方案--------------------------------------------------------
[bo][un]柒雨晴[/un] 在 2008-6-27 01:10 的发言:[/bo]

我是一只刚刚入门的小小菜鸟..  


因为基础较差(都是因为以前上的破电脑学校)

最近刚学到数据类型..

感觉有一些东西似懂非懂. 学得有一点吃力..

就是关于 补码 进制 之类的 汇编基础吧 不太懂..

   ...


没必要深究

后边有位运算,你只要知道有溢出就可以了
----------------解决方案--------------------------------------------------------
溢出我知道.. 谢谢楼上的..
下面是我刚看的一篇文章..
----------------解决方案--------------------------------------------------------
闲扯原码、反码、补码

   相信大家看到这个标题都不屑一顾,因为在任何一本计算机基础知识书的第一章都有他们的解释,但是在书上我们只能找到一些简单的定义,没次看过之后不久就忘了。最近论坛里有人问起这些概念,看到很多人的回复是以前看过现在忘了去看看某某书之类,很少有给出一个合理的解释。于是本人就开始思考(虽然上帝会发笑,我还是要思考。),于是得出了以下的结论。


     数值在计算机中表示形式为机器数,计算机只能识别0和1,使用的是二进制,而在日常生活中人们使用的是十进制,"正如亚里士多德早就指出的那样,今天十进制的广泛采用,只不过我们绝大多数人生来具有10个手指头这个解剖学事实的结果.尽管在历史上手指计数(5,10进制)的实践要比二或三进制计数出现的晚."(摘自<<数学发展史>>有空大家可以看看哦~,很有意思的).为了能方便的与二进制转换,就使用了十六进制(2 4)和八进制(23).下面进入正题.

数值有正负之分,计算机就用一个数的最高位存放符号(0为正,1为负).这就是机器数的原码了.假设机器能处理的位数为8.即字长为1byte,原码能表示数值的范围为

(-127~-0 +0~127)共256个.

  有了数值的表示方法就可以对数进行算术运算.但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下: 假设字长为8bits

( 1 ) 10-  ( 1 )10 =  ( 1 )10 + ( -1 )10 =  ( 0 )10

(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 显然不正确.

  因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上,对除符号位外的其余各位逐位取反就产生了反码.反码的取值空间和原码相同且一一对应. 下面是反码的减法运算:

( 1 )10 -  ( 1 ) 10=  ( 1 ) 10+ ( -1 ) 10=  ( 0 )10

(00000001) 反+ (11111110)反 =  (11111111)反 =  ( -0 )  有问题.

( 1 )10 -  ( 2)10 =  ( 1 )10 + ( -2 )10 =  ( -1 )10

(00000001) 反+ (11111101)反 =  (11111110)反 =  ( -1 ) 正确

问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的.(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大).

于是就引入了补码概念. 负数的补码就是对反码加一,而正数不变,正数的原码反码补码是一样的.在补码中用(-128)代替了(-0),所以补码的表示范围为:

(-128~0~127)共256个.

注意:(-128)没有相对应的原码和反码, (-128) = (10000000)  补码的加减运算如下:

( 1 ) 10-  ( 1 ) 10=  ( 1 )10 + ( -1 )10 =  ( 0 )10

(00000001)补 + (11111111)补 =  (00000000)补 = ( 0 ) 正确

( 1 ) 10-  ( 2) 10=  ( 1 )10 + ( -2 )10 =  ( -1 )10

(00000001) 补+ (11111110) 补=  (11111111)补 = ( -1 )  正确

   所以补码的设计目的是:

     ⑴使符号位能与有效值部分一起参加运算,从而简化运算规则.

⑵使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计

  所有这些转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。看了上面这些大家应该对原码、反码、补码有了新的认识了吧!



  



作者Blog:http://blog.csdn.net/fengzi_zhu/
----------------解决方案--------------------------------------------------------
下面这点儿内容是原创的。

  移码

  现在,我们做加法运算是没有问题了,可是比较操作怎么办呢?我们该怎样实现比较的操作呢?

  我们知道,比较容易想到的一个解决方案就是做减法,如果减的结果为0则相等;是负数,则减数小于被减数;反之,减数大于被减数。我们看下面的一个例子。

  (-2)10 - (1)10 = (-3)10 小于0,所以-2小于1

  这样我们得到了一个补码比较的解决方案,根据相减的结果来判断大小。

  但是我们又注意到,其实补码的减法是比较复杂的。需要首先对被减数求反,然后相加。加法还会涉及到进位的问题,虽然因为可以使用加法器而能简化电路的设计,但是这样明显拖慢了时间,如果需要大量比较,则会显得得不偿失。我们能不能找到简单的方法,来获得两个数之间的大小关系呢?

  可以!想想看,我们比较十进制是怎么比较的?先看位数,位数大的数字肯定大,如果位数相同,则比较第一位的大小,再顺次下来比较。对于二进制,这明显也是最快速的方法。我们从高向低诸位比较,对遇到的第一个不同的位进行判断,该位为1的数字比该位为0的数字“大”,如果到最低位还是相同,则代表两个数字相等。这种算法的运算速度相比做减法是极快的,因为各位单独比较,不涉及到进位。

  但是,慢着!天下没有免费的午餐,我们一开始就遇到了一只“拦路虎”:按照这样的定义,正数和正数,负数和负数的比较都是合法的,但是恰恰正数和负数的比较会出现问题,因为负数第一位是1,所以造成了全体的负数比全体的正数都要大,这明显不符合逻辑!

  移码就是为了解决这个矛盾而产生的。移码编码的相对位置和补码相同,只是加上了一个特定的数字,从而和对应的补码表示“错开”了一段距离,使得负数能“回到”比正数小的位置(请在这里,将二进制串想象成一个“环”,不停地加一循环地环。当达到1111 1111的时候,再加一,就会返回到0000 0000,反复循环下去)。

  最典型的移码是给补码加上2的次幂,比如对于一个8位的整数,其补码范围是-128~127,而-128的二进制表示是(1000 0000)2,我们在这个数字的基础上加上2^7=(1000 0000)2,这样它就等于0了(注意溢出)。

  我们可以得到补码和移码(这里是2^7移码)的关系:

程序代码:
  原码           补码           移码
  -128           1000 0000      0000 0000
  0              0000 0000      1000 0000
  127            0111 1111      1111 1111


  你看,移码的名字就是这么来的,好像是把补码给“移了”几个位置,本来是表示某个值的被移到了另外的地方。而从上面的表就可以看出,补码表示中,各元素的大小是很“自然”的,无论是二进制码,还是原码,其大小排列的顺序都是相同的,所以特别适合比较。但是,补码不能直接用来计算,必须要还原成补码,才能运算后得到正确的结果。

  补码广泛运用在需要大量比较,而计算较少的场合。比如浮点数的阶码就是由补码表示的。

  从上面的叙述可以看出,计算机中复杂的数字表示法,都是根据需要,在原先的基础上逐步地改进而渐渐产生的。这样的规律其实也适用于其他的研究。只有认真研究需求,分析效率最高的方法,才能写出高效的代码,才能创造更多的收益!

  打这么多字好累啊……LZMM你说我是不是应该复制一份,再发个原创贴呢?………………

[[it] 本帖最后由 StarWing83 于 2008-6-27 02:16 编辑 [/it]]
----------------解决方案--------------------------------------------------------
[bo][un]StarWing83[/un] 在 2008-6-27 02:01 的发言:[/bo]

打这么多字好累啊……LZMM你说我是不是应该复制一份,再发个原创贴呢?………………


我鄙视爱发原创的人
见一次打击两次

编码问题在很多书中都会讲到,计算机组成原理中讲的多一点。组成原理不仅讲如何编码,还有CPU如何在硬件上实现相关编码的运算。
----------------解决方案--------------------------------------------------------
原码、反码、补码 三种码在值为正整数的时候结果都是一样的;
为负数的时候,反码是原码的按位取反;而补码是原码的按位取反+1.
----------------解决方案--------------------------------------------------------

  太感动了.. 谢谢各位大大~~
----------------解决方案--------------------------------------------------------
http://6.cn/profile/list.php?t=v&u=13844692&o=t&page=23


http://u.youku.com/user_playlist/id_UMTUwNzA0MzI=

计算机组成原理视频

[[it] 本帖最后由 柒雨晴 于 2008-6-27 15:02 编辑 [/it]]
----------------解决方案--------------------------------------------------------
你自己留着看吧
----------------解决方案--------------------------------------------------------
  相关解决方案