社区
C语言
帖子详情
补码运算问题
wit2188
2007-10-05 05:31:41
int长度为2,-32768的二进制数为1000000000000000,可怎么看这都是-0,怎么表示-32768呢?有人说什么补码,有点不解,还望指教。
...全文
5530
27
打赏
收藏
补码运算问题
int长度为2,-32768的二进制数为1000000000000000,可怎么看这都是-0,怎么表示-32768呢?有人说什么补码,有点不解,还望指教。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
27 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
hhaoxuezheh
2012-07-04
打赏
举报
回复
x的8位补码是10110100,则x的16位的补码是多少啊?
xuzizhou
2011-11-05
打赏
举报
回复
这个理解了,有谁知道补码的运算是怎么回事吗,一直没弄清楚
fairywell
2010-12-14
打赏
举报
回复
-32768不能用 16bits 表示,so,如果用 17bits 表示,就是
-32768 -> 1_1000 0000 0000 0000 -> 1_0111 1111 1111 1111 -> 1_1000 0000 0000 0000
这里玩了个概念偷换,感谢你的帖子,和 23楼 xxMix 兄的解答,我开始也晕了
xuzhaohua38
2010-09-09
打赏
举报
回复
有一个公式算的
xxMix
2010-05-13
打赏
举报
回复
今天刚遇到这个问题,没想到老帖居然有问。。我同意20楼的观点,但我觉得他么明白楼主的意思。而拿分的16楼,根本没搞清楼主问题的症结所在。。楼主居然把分给他,真想不通。。
我局的楼主之所以纠结,是因为这个问题与课本相违背。
首先看看楼主的问题:
[Quote=引用楼主 wit2188 的发言:]
int长度为2,-32768的二进制数为1000 0000 0000 0000,可怎么看这都是-0,怎么表示-32768呢?有人说什么补码,有点不解,还望指教。
[/Quote]
楼主错就错在搞不清概念和符号。
首先,10进制的 32768,转换为2进制数,是 1000 0000 0000 0000。楼主说:-32768的二进制数为1000 0000 0000 0000,可见楼主一开始就错了。
其次,10进制的 -32768,转换为2进制数,是 - 1000 0000 0000 0000。
根据源码的定义,
设 X = ( -32768 )10进制 = ( -1000 0000 0000 0000 )2进制数
所以 [X]源码 = 2^16 - X
= 1 0000 0000 0000 0000 - ( -1000 0000 0000 0000 )
= 1 0000 0000 0000 0000 + 1000 0000 0000 0000
= 1 1000 0000 0000 0000
即 ( -32768 )10进制 = ( 1_1000 0000 0000 0000 )2进制源码,17位了,无法用16位来表示。
所以,必须进行人为规定。
接着,我们来看看规定的过程:
首先观察:
10进制 -> 2进制源码,16位 -> 2进制反码,16位 -> 2进制补码,16位
-1 -> 1_000 0000 0000 0001 -> 1_111 1111 1111 1110 -> 1_111 1111 1111 1111
-2 -> 1_000 0000 0000 0010 -> 1_111 1111 1111 1101 -> 1_111 1111 1111 1110
-3 -> 1_000 0000 0000 0011 -> 1_111 1111 1111 1100 -> 1_111 1111 1111 1101
................................................................................
-32765 -> 1_111 1111 1111 1101 -> 1_000 0000 0000 0010 -> 1_000 0000 0000 0011
-32766 -> 1_111 1111 1111 1110 -> 1_000 0000 0000 0001 -> 1_000 0000 0000 0010
-32767 -> 1_111 1111 1111 1111 -> 1_000 0000 0000 0000 -> 1_000 0000 0000 0001
我们发现:从上向下看:
10进制 是 递减1的。
2进制源码,16位 是 递增1的。
2进制反码,16位 是 递减1的。
2进制补码,16位 是 递减1的。
所以,我们根据这个规律,人为的在下面添加一个 -32768,使之符合这个规律。
但现在,我们面临一个选择,有源码、反码和补码,到底是选谁来作为参考标准呢?
如果我们从2进制源码,16位入手,最后一个 ( -32767 )10 -> 1_111 1111 1111 1111 加1,我们不知道符号是否应该参加运算,所以不用它。
如果我们从2进制反码,16位入手,最后一个 ( -32767 )10 -> 1_000 0000 0000 0000 减1,我们不知道符号是否应该参加运算,所以也不用它。
现在剩下的只有反码,最后一个 ( -32767 )10 -> 1_000 0000 0000 0001 减1,刚好是 1_000 0000 0000 0000 ,因此我们选择用它来推算出 ( -32768 )10。
于是,它就诞生了:
10进制 -> 2进制源码,16位 -> 2进制反码,16位 -> 2进制补码,16位
-1 -> 1_000 0000 0000 0001 -> 1_111 1111 1111 1110 -> 1_111 1111 1111 1111
-2 -> 1_000 0000 0000 0010 -> 1_111 1111 1111 1101 -> 1_111 1111 1111 1110
-3 -> 1_000 0000 0000 0011 -> 1_111 1111 1111 1100 -> 1_111 1111 1111 1101
................................................................................
-32765 -> 1_111 1111 1111 1101 -> 1_000 0000 0000 0010 -> 1_000 0000 0000 0011
-32766 -> 1_111 1111 1111 1110 -> 1_000 0000 0000 0001 -> 1_000 0000 0000 0010
-32767 -> 1_111 1111 1111 1111 -> 1_000 0000 0000 0000 -> 1_000 0000 0000 0001
................................................................................
-32768 -> -------------------- -> -------------------- -> 1_000 0000 0000 0000
因此 -32768 的反码是 1000 0000 0000 0000
lingxixiaopang
2008-10-29
打赏
举报
回复
-32768 转成补码
第一步:求32768补码 0000000000000000 1000000000000000
第二步:对0000000000000000 1000000000000000 取反 得1111111111111111 0111111111111111
第三步:11111111111111110111111111111111 + 1 =1111111111111111 1000000000000000
这是32位的结果.
补码(1000000000000000) 转成 10进制
第一步:1000000000000000 按位取反 得 0111111111111111
第二步:0111111111111111 转成10进制 得32767
第三步:32767前面加-号 再减1 得 -32768
这么兜了一圈 看得明白吗?
钱塘工匠
2008-08-30
打赏
举报
回复
比如,16位float型符点数存储时,为什么指数偏移量是127,为什么?那是IEEE标准规定的,规定这东西,较劲,有点浪费时间.先记着,用熟了,说不定就能悟出人家规定的理由了.呵呵
钱塘工匠
2008-08-30
打赏
举报
回复
我一直是这样子想的:
以八位来说,小写点:
00000000->0x00无异议吧
11111111->-0x7f
01111111->+0x7f
那这七位,还有一个资源没用,
那就是
10000000->-0x00,这里面,不是数学领域,负什么零,还不如分配给最小位好了,所以就分给-0x80了,
那有朋友要问了,为什么不分给+0x80呢?
你可以问下比尔,盖茨,为什么叫bill.gates,而不叫比尔克林顿,那就是总统了.哈哈...
q421602022
2007-10-08
打赏
举报
回复
那么-1在内存中的表示就是1111 1111 1111 1111,计算机就用它来进行运算。我原先知道一个二进制数可以按权展开得到十进制数,可在这里就碰了壁,1111 1111 1111 1111按权展开后的结果显然不是-1,这就让我十分之迷惑,我上面一再问的就是这个问题,可惜没人能对症下药。我实在搞不清诸位是为了分还是为了帮助别人,并在这同时,也提升自己,所谓温故知新吗。如果只是为了分,那好理解,他肯定在想:“只要有分就成,具体你在问什么我不必太在意”。可在我看来这分实在没什么意思,如果能拿这分换点什么二手货、次货或淘汰货之类的,还有点意思,可以当成一个游戏玩,可惜不是。实际上,我相信稍微成熟一点的,都应该认识到了这点,我也相信在这里做解答的,大多都有这个认识。既然这样,那么做解答的大多数应该是为了帮助别人,提高自己。如果真是这样,那么希望你们做解答前先把问题看清楚。如上,那个二进制代码是补码,所以得不出-1,要想得到-1,就必须把补码换成原码,也就是机器数,然后再按权展开才成。求补码的原码就是求补码的补码,1111 1111 1111 1111符号位不变,后面取反加1得1000 0000 0000 0001,此为-1原码,按权展开亦可得-1。如此解释才能解决为什么从补码得不到原十进制数的原因,也就解决了我一直在问的东西。
楼主到底是问什么啊....你不是问为什么会发生吗?
你那点分真的到底能做什么
而且你当你是什么 每个人那么热情的回答你就这样抨击人家 太过分了吧 你那几分 不稀罕也罢
wit2188
2007-10-06
打赏
举报
回复
呵呵,目前倒没有必要去深究原理,只不过c语言的学习迫使我要把这些东西弄清楚才成。
倒不是一时气话,我的确认为在这里做解答的分为两大类人,一类是对分有兴趣的,另一类则不是,具体是什么就不好说了。
mx81831
2007-10-06
打赏
举报
回复
另外对于溢出的处理是计算机低层硬件电路完成的,不同体系结构的计算机可能对于溢出处理不一样。
但在I32的计算机中1000000000000000为-32768,(arong1234 )他解释是应该是正确的。
你如果对低层计算机的实现有兴趣,应该深入了解微机原理方面的知识。
PS:
我实在搞不清诸位是为了分还是为了帮助别人,并在这同时,也提升自己,所谓温故知新吗。如果只是为了分,那好理解,他肯定在想:“只要有分就成,具体你在问什么我不必太在意”。可在我看来这分实在没什么意思,如果能拿这分换点什么二手货、次货或淘汰货之类的,还有点意思,可以当成一个游戏玩,可惜不是。实际上,我相信稍微成熟一点的,都应该认识到了这点,我也相信在这里做解答的,大多都有这个认识。
以上这段话,我觉得LZ说的不好,也许是一时的气话。
mx81831
2007-10-06
打赏
举报
回复
计算机处理负数时是按补码来处理,而人来处理负数时习惯用10进制来处理,要把补码还原成10进制,正如LZ说的那样要把补码变为原码后按权展开。这个问题说明了一个数的不同表示法。
就好比一个光波,可以在时域用时间表示,还可以在频域用频率表示的道理一样。
wit2188
2007-10-06
打赏
举报
回复
诸位说得都有一些道理,但一直没说到我问的关键上。
自己思考一番后,我现在知道-32768在内存中的存储是1000 0000 0000 0000,但这个二进制代码是补码,这一点很重要,一个二进制数,如果你把它看成带符号的,那么它就是补码,计算机只用补码来进行运算。
例如-1,它的表示有:
原码:1000 0000 0000 0001
反码:1111 1111 1111 1110
补码:1111 1111 1111 1111
那么-1在内存中的表示就是1111 1111 1111 1111,计算机就用它来进行运算。我原先知道一个二进制数可以按权展开得到十进制数,可在这里就碰了壁,1111 1111 1111 1111按权展开后的结果显然不是-1,这就让我十分之迷惑,我上面一再问的就是这个问题,可惜没人能对症下药。我实在搞不清诸位是为了分还是为了帮助别人,并在这同时,也提升自己,所谓温故知新吗。如果只是为了分,那好理解,他肯定在想:“只要有分就成,具体你在问什么我不必太在意”。可在我看来这分实在没什么意思,如果能拿这分换点什么二手货、次货或淘汰货之类的,还有点意思,可以当成一个游戏玩,可惜不是。实际上,我相信稍微成熟一点的,都应该认识到了这点,我也相信在这里做解答的,大多都有这个认识。既然这样,那么做解答的大多数应该是为了帮助别人,提高自己。如果真是这样,那么希望你们做解答前先把问题看清楚。如上,那个二进制代码是补码,所以得不出-1,要想得到-1,就必须把补码换成原码,也就是机器数,然后再按权展开才成。求补码的原码就是求补码的补码,1111 1111 1111 1111符号位不变,后面取反加1得1000 0000 0000 0001,此为-1原码,按权展开亦可得-1。如此解释才能解决为什么从补码得不到原十进制数的原因,也就解决了我一直在问的东西。
道理大家都知道,可没答到点子上不感觉自己做了很多无用功吗?
题外话,这个道理和打架也是相通的,两人对招,高手必定要尽力看出对方弱处,以求一击必中。
q421602022
2007-10-05
打赏
举报
回复
“此时得到得已经不是开始要计算得东西了,系统知道这是一个绝对值,因此得到是32768”
迷惑,能否说说是怎么得到32768的,感觉好像没解释。你运算的结果居然和原先一样,这样的结果我前面也得出了,还是不解。我前面问的够明白了,不知该怎么问了。
----看我的帖 他是胡说八道...说的含糊
$许松(255****) 19:38:37 [来自群9246398给你的答复]
“此时得到得已经不是开始要计算得东西了,系统知道这是一个绝对值,因此得到是32768”没学过计算机我们有个专用词:计盲
$ sen<*****@gmail.com> 19:38:38
这么能用那么钝的人
$许松(255****) 19:39:05
那人是个计盲
wit2188
2007-10-05
打赏
举报
回复
“此时得到得已经不是开始要计算得东西了,系统知道这是一个绝对值,因此得到是32768”
迷惑,能否说说是怎么得到32768的,感觉好像没解释。你运算的结果居然和原先一样,这样的结果我前面也得出了,还是不解。我前面问的够明白了,不知该怎么问了。
q421602022
2007-10-05
打赏
举报
回复
写的好辛苦...来这里真是受罪...希望漏主懂我懂的那样~!~嘿嘿~!~
q421602022
2007-10-05
打赏
举报
回复
int长度为2,-32768的二进制数为1000000000000000,可怎么看这都是-0,怎么表示-32768呢?有人说什么补码,有点不解,还望指教。
就两种编码来说:
原码表示:
X符号位,[真值]
0000000000000000 -> 0 就是0
1000000000000000 -> 就是-0
0111111111111111 -> 是32767
1111111111111111 -> 是带负号的 32767 ,-32768 你要的表示不能这么多位里实现 (因为里面重复+0 -0用了一个座位啊 呵呵)
补码表示:
0000000000000000 -> 0是正符号位,正数,还是0~
1000000000000000 -> 1是负符号位,逆转 1后面的000000000000000为111111111111111 就是32767,加上1补回来就是-32768
0111111111111111 -> 0是正符号位,正数,是后面的表达,32767
1111111111111111 -> 1是负符号位,逆转后面(c里面符号~),000000000000000是0,加上1,就是十进制的1了~
arong1234
2007-10-05
打赏
举报
回复
你是不是另外开贴问过,我记得回答过你
计算很简单,对于1000 0000 0000 0000
1. 检查高位,知道这是一个负数
2. 对位全部取反,得到0111 1111 1111 1111
3. 对2得到得数加1
就得到1000 0000 0000 0000
注意:此时得到得已经不是开始要计算得东西了,系统知道这是一个绝对值,因此得到是32768
4. 加上符号位就是-32768
wit2188
2007-10-05
打赏
举报
回复
多谢,可依然不解。
我知道32767+1可以得到-32768
0111 1111 1111 1111
+ 0000 0000 0000 0001
******************************
1000 0000 0000 0000
但就是不知道这个1000 0000 0000 0000是怎么转变成-32768,你说不能按权展开,那它总要通过某种运算得到-32768,否则怎么知道1000 0000 0000 0000就是-32768,至少用我已知的知识就没法解释。你应该看出来了,我肯定欠缺了某方面的知识,所以如此迷惑。这方面知识好像是补码运算。
q421602022
2007-10-05
打赏
举报
回复
补码
用[x]表示机器数(原码),x是真值(二进制)
x=+0.1001,则[x]原=0.1001
x=-0.1001,则[x]原=1.1001
对于0,原码中有“+0”、“-0”之分,故有两种形式:
[+0]原=0.000...0
[-0]原=1.000...0
采用原码表示法简单易懂,但它的最大缺点是加法运算复杂。这是因为,当两数相加时,如果是同号则数值相加;如果是异号,则要进行减法。而在进行减法时还要比较绝对值的大小,然后大数减去小数,最后还要给结果选择符号。
为了解决这些矛盾,人们找到了补码表示法。机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。
负数用补码表示时,可以把减法转化为加法。这样,在计算机中实现起来就比较方便
[x]补= { x 1>x≥0
{ 2+x=2-|x| 0≥x≥-1
x=+0.1011,则[x]补=0.1011
x=-0.1011,则[x]补=10+x=10.0000-0.1011=1.0101
对于0,[+0]补=[-0]补=0.0000 (mod 2)
例子中是以定点小数为例。
补码的原理可以用钟表来描述
如设标准时间为4点正;一只表已经7点了,为了校准时间,可以采用两种方法:一是将时针退 7-4=3 格;一是将时针向前拨12-3=9格。即7-3和7+9(mod12)等价,因此,把负数用补码表示的mod2操作,可以把减法转化为加法。
加载更多回复(7)
计算机组成原理第二章-
运算
方法与
运算
器
计算机中的数据表示,熟悉包括定点数、浮点数、字符、十进制数的表示方法 ; 原码、
补码
、反码、移码等码制之间的关系以及各码制之间真值数的转换;
补码
的加减
运算
,定点原码一位乘、除
运算
,定点
补码
一位乘、除
运算
及其逻辑结构; 变形
补码
、
运算
方法(尤其是
补码
)的理解,溢出、进位等
问题
的出现和解决方法; 定点数的变形
补码
加减
运算
; 原、
补码
乘法和除法
运算
; 浮点
运算
方法和浮点数的规格化及其逻辑结构;
运算
器的基本结构和设计方法,解已知芯片功能。
计算机CPU处理
运算
补码
运算
补码
运算
溢出原理与处理
补码
运算
-溢出和自然丢弃
补码
运算
-溢出和自然丢弃 int :-32768——+32767 最高位为符号位:0代表正,1代表负 正数:
补码
,反码,原码相同 负数:
补码
是正数取反加一 32767 的编码0111111111111111 取反为1000000000000000 再加1得到-32767的编码: 1000000000000001 -32768比32767还少1:自然就是: 1000000000000000 在原码
运算
时,首先要把符号与数值分开。例如两数相加,先要判断两数的符号,如果同号,可以做加法,如果异号,实际要做
FPGA仿真调试经验-
补码
运算
通过仿真发现16'd1154取
补码
后为-16'd31614,显然是不对的。此时已经定位
问题
所在,只需排查即可找出
问题
,通过排查发现是将符号位也同时取反了。在调试中我犯一个错误,在却
补码
运算
中将符号位也同时取反,导致仿真结果出错。在FPGA中进行
补码
运算
,首先将变量声明为signed。最高位为符号位,0表示正数,1表示负数。等于本身,负数的
补码
等于反码+1。首先明确什么是
补码
?
补码
的
运算
补码
的
运算
补码
的算术
运算
补码
运算
要注意的
问题
:1.
补码
运算
时,其符号位与数值部分一起参加
运算
。 2.
补码
的符号位相加后,如果有进位出现,要把这个进位舍去(自然丢失)。 3.用
补码
运算
,其
运算
结果亦为
补码
。在转换为真值时,若符号位为0,数位不变;若符号位为1,应将结果求补才是其真值。 [例3] 已知X = + 1101 , Y = + 0110 , 用
补码
计算Z = X-Y。 解: [X]补 = 01101,[-Y]补 = 11010,则[Z]补 =[X]补+[-Y]补 = 01
C语言
70,031
社区成员
243,245
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章