用2进制表示负数的疑问

znevq 2012-03-29 11:36:24
这个问题就结了许久呀,还是不能想明白,不知道是不时我钻牛角尖了
先说明以下都是在int占2字节的情况下的
比如-10用2进制表示的话,过程如下:
10的原码 0000 0000 0000 1010
取反 1111 1111 1111 0101
加1 1111 1111 1111 0110

这个也就是10的补码,也就是说在计算机中-10是以这个1111 1111 1111 0110存储-10的

然后可以知道这个1111 1111 1111 0110的最高位是符号位 表示该数为负数

然后我就不太明白了:
如果这个数是有符号型,那么由2进制表示法求得它等于-32758
如果这个数是无符号型,那么由2进制表示法求得它等于 65526

但是-32758在计算机中是以1000 0000 0000 1010这个补码存储的
而65526我用计算器 在int=2字节的模式下 却无法表示 貌似是默认成无符号型的了

现在我的理解是:
这个1111 1111 1111 0110只是代替-10存储进计算机的数,并没有实际意义。

这个疑惑求高手帮忙解答一下!!!
...全文
205 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
znevq 2012-03-30
  • 打赏
  • 举报
回复
恩 默认是2字节的情况下
多谢你了
也感谢前面几位朋友!
muyi66 2012-03-30
  • 打赏
  • 举报
回复
呃,要注意的是你的int型必须是16位的位长,否则就不会把它看作是负数了。
muyi66 2012-03-30
  • 打赏
  • 举报
回复
对的,存进去的过程里机器什么都没改变。但因为对它的看法不同,值就不同了。
znevq 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
应该说是在转化为10进制文本时需要做这样的处理,如果是保存在内存作为二进制数据,那就直接用补码表达了。

无符号数还是有符号数对CPU来说都一样,它都同样对待。我们在汇编语言里要靠程序员自己标记/注释一个变量是否带有符号,而高级语言里就可以直接定义它是否带有符号,让编译器去头疼。

所以,用C语言写程序的话,你把1111 1111 1111 0110存进unsigned short型变量里……
[/Quote]
也就是说 把它存进unsigned int里面,它=65526,存进int里面,它=-10,是这样的吗?
muyi66 2012-03-30
  • 打赏
  • 举报
回复
应该说是在转化为10进制文本时需要做这样的处理,如果是保存在内存作为二进制数据,那就直接用补码表达了。

无符号数还是有符号数对CPU来说都一样,它都同样对待。我们在汇编语言里要靠程序员自己标记/注释一个变量是否带有符号,而高级语言里就可以直接定义它是否带有符号,让编译器去头疼。

所以,用C语言写程序的话,你把1111 1111 1111 0110存进unsigned short型变量里,他就是个无符号数;你把它存进short型变量里,它就是个有符号数。
znevq 2012-03-30
  • 打赏
  • 举报
回复
很感谢楼上几位的说明
我大概理解了
我现在这么理解对不对

1111 1111 1111 0110 直接把最高位的1按照符号位表示负,其他位相加得32758它表示-32758
以上这个做法就是错误的,因该是:
只要是有符号位的数,都是按照取反加1返回其正数原码载加负号,也就是它应该是0000 0000 0000 1010所表示的10,再加负号得-10

再一个问题就是1111 1111 1111 0110能表示无符号型的整数63326吗?
如果可以的话,那么如何知道这个类型的数字是负数的补码还是无符号型的数呢?
starsoft007 2012-03-30
  • 打赏
  • 举报
回复
嗯,注意规则要一致。
你用补码存储的,读取的时候当让也要按补码的方式读取啊。
不能说你存了一个补码,然后按原码来用,那肯定就不对了,是吧。
BadPattern 2012-03-30
  • 打赏
  • 举报
回复
1111 1111 1111 0110 = 五个bit位表示的值 1 0110 = (-16+4+2) = -10
这也是小数(k位)转化成大数(w位)的做法,即直接加上个w-k个符号位
东旭 2012-03-29
  • 打赏
  • 举报
回复
首先,程序在调用你的一个数据时,先看你是什么类型,如果是unsigned int/char 型的,都会按照正数处理
如果是int/char ,会先看最高位,如果最高位是0,按照正数处理,如果是1,它就知道这是一个负数的补码,在调用时会自动转化成实际的负数,不需要你操心。
muyi66 2012-03-29
  • 打赏
  • 举报
回复
比如1111 1111 1111 1111表达的不是-32767,而是-1。你不能直接把负数的符号位除开就用其它位计算它的绝对值,只能用补码方式再次求补,得到答案0000 0000 0000 0001——绝对值1,符号为负,这才是答案。

采用补码表达法的好处是可以直接用加法器来计算减法,也能直接计算含有负数的加法。比如-1+10:
1111 1111 1111 1111
0000 0000 0000 1010
-------------------
0000 0000 0000 1001
直接就能得到答案:9

再看-5+3:
1111 1111 1111 1011
0000 0000 0000 0011
-------------------
1111 1111 1111 1110
也是直接得到答案:-2

补码表达法除了不能直接计算乘法外,其它3种四则运算都会变得很容易。有什么理由不用呢?
muyi66 2012-03-29
  • 打赏
  • 举报
回复
补码表示法中,1111 1111 1111 0110表示的是-10,不知道你说的-32758是怎么来的。如果你把符号位除开之后其它各位加权计算出来,那个算法是错误的。计算机中没有采用那样的表达方式。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧