请教 数据类型 补码方面..
我是一只刚刚入门的小小菜鸟.. 因为基础较差(都是因为以前上的破电脑学校)
最近刚学到数据类型..
感觉有一些东西似懂非懂. 学得有一点吃力..
就是关于 补码 进制 之类的 汇编基础吧 不太懂..
请教大虾门, 有什么办法可以补一补这方面的知识..
教程或者 有什么书.. 越易懂越好..
----------------解决方案--------------------------------------------------------
[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
-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你说我是不是应该复制一份,再发个原创贴呢?………………
打这么多字好累啊……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]]
----------------解决方案--------------------------------------------------------
你自己留着看吧
----------------解决方案--------------------------------------------------------