位域/位段/bit field :输入+256,打印-256,请教原因
进制 位域 相关的的问题;插入代码(问题在注释里面):
#include<stdio.h>
/*IDE&Compile:C-Free 5.0;
*Attar:C语言 ;
*TIME:2013年7月18日07:12:08;
*ABOUT:你知道,这是个非常有趣的代码当你输入+256的时候,打印的结果是-256;
*我也不知道这是什么情况,待处理中...
* doing...
*/
int main(void){
struct{
int n:9;
/*测试的结果是:n:8以下..==0;
n:8== 0;
n:9==-256
n:10==256
n:11==256
n:12以上 ..==256;
*/
}bin;
bin.n=256;
printf("The bin.n =%d ;\n",bin.n);
return 0;
}
还有我自己的理解:
操作系统:Win Xp sp3 32bit;
(DEC)256=(BIN)1 0000 0000
0000 0001 0000 0000 (最高位是1,所以是负数)//剩余的8位全部是0,-0,好像又不对,
0000 0001 0000 0000=1 0000 0000; 本帖最后由 ryxcaixia 于 2015-7-20 11:40 编辑
楼主 计算机组成原理里层曰 : 在计算机中, 无论正数还是负数都一律采取补码表示
正数的补码还是自己, 负数的补码则是取反加1
楼主 我接着你的说
(DEC)256=(BIN)1 0000 0000
0000 0001 0000 0000 (最高位是1,所以是负数)//剩余的8位全部是0,-0,好像又不对,
0000 0001 0000 0000=1 0000 0000;
此时最高位为1, 为负数, 剩下的8位都是0, 但不代表这玩意(1 0000 0000)是负0
所代表的是0000 0000 取反(因为是负数) 就是 0xFF, 然后再加1, 即256
楼主你可以这么试一下
char n1 = 0xFF;
unsign char n2 = 0xFF;
然后打印出来
如图所示, char 和unsign char 都是8位一个字节
不同的是最高位是否为符号位
有符号的就代表为-1(取反后再减1 过程刚好逆过来)
无符号的就代表255 int main(void){
struct{
int n:9;
/*测试的结果是:n:8以下..==0;
n:8== 0;
n:9==-256
n:10==256
n:11==256
n:12以上 ..==256;
*/
}bin;
bin.n=256;
printf("The bin.n =%d ;\n",bin.n);
for (int i = 31; i >= 0; i--)
printf("%d", (bin.n >> i) & 0x0001);
return 0;
}
再添加一段代码 这段代码可以打印出变量在内存中的真实形状 ryxcaixia 发表于 2015-7-20 07:14
楼主 计算机组成原理里层曰 : 在计算机中, 无论正数还是负数都一律采取补码表示
正数的补码还是自己, 负 ...
非常感谢,你又一次帮我解决问题了。谢谢:handshake ryxcaixia 发表于 2015-7-20 07:14
楼主 计算机组成原理里层曰 : 在计算机中, 无论正数还是负数都一律采取补码表示
正数的补码还是自己, 负 ...
==我好想还是没搞懂,255+1的确是256; 但是,问题是我还是没明白,正数输入256打印的是负数256?为啥呢。
当我输入正数256;(有符号,位域限制 9bit);打印的结果是负数256;
struct bin_field{
int n:9;
ungsigend int un:9;
}bin;
bin.n=256,bin.un=256;
打印结果是:bin.n=256,bin.un=-256;
256= 1 0000 0000;原码
1 1111 1111;反码(取反)
10 0000 0000;补码(加 1) 本帖最后由 ryxcaixia 于 2015-7-21 17:16 编辑
这里int n:9
然后bin.n=256; 256就是(1 0000 0000)
此时 计算机内对于n的解释是(1 0000 0000) 这9个数字 这个是补码 计算机只认识补码 原码都是计算出来的
然后解释 这个东西
1 0000 0000 -> 因为这个东西是有符号的 至于为啥 是因为你定义的时候用的是 int 而不是unsigned, 所以 计算机会去这个1 0000 0000中去找最高位 来判定此值的正负 计算机一看 卧槽 这是个负数 然后自动计算下取反加1 这个东西是啥 一算 啊 原来是256 加上负号 就是-256
如果是楼主 你定义的 unsigned int un:9
然后bin.un = 256
1 0000 0000
计算机一看 卧槽 这是个无符号的(编译期确定 unsigned), 所以这玩意肯定是个大于等于0的, 然后直接计算一下1 0000 0000 算出256 ryxcaixia 发表于 2015-7-21 17:12
这里int n:9
然后bin.n=256; 256就是(1 0000 0000)
此时 计算机内对于n的解释是(1 0000 0000) 这9个数字 ...
麻烦解决下这几个疑惑/
无符号的我懂,就是有符号的不太懂;
1 0000 0000 ;这是256的二进制;那么也就是原码了?最高位是1,判断是负数;
1 1111 11111;然后取反;
10 1111 1111;再加1,就是补码;但是,如果反码加1的话,符号位参与运算吗?
如果参与:就是 10 1111 1111;
如果不参与;就是1 1 0000 0000;
1 1111 1111(取反后的256;)
0 0000 0001 +(加1)
------------
? 0000 0000;(补码,那个问号表示后面怎么算,当溢出遇见符号位时)
1 0000 0000 ;这是256的二进制;那么也就是原码了?最高位是1,判断是负数;
所有的数据在计算机中都以补码形式存在
256是一个正数, 为啥是正数呢 因为你写的就是256 如果是负数你会写-256
然后 256的 对应二进制是 1 0000 0000 这个东西是补码 只因为256 是正数 所以 这个东西同时也是原码
计算机组成原理曰 正数的补码就是原码本身
bin.n = 256;
等号右边的那个东西叫做常量, 不管正数 他就是1 0000 0000
然后 把这个东西赋值给变量了, 即bin.n
但是这个bin.n怎么解释1 0000 0000取决于你给他的定义是什么
如果是无符号的, 那么直接解释 1 0000 0000
如果是有符号的, 你懂的, 去反加1
1 1111 11111;然后取反;
10 1111 1111;再加1,就是补码;但是,如果反码加1的话,符号位参与运算吗?
符号位打死都不参与运算
如果参与:就是 10 1111 1111;
如果不参与;就是1 1 0000 0000;
? 0000 0000;(补码,那个问号表示后面怎么算,当溢出遇见符号位时)
溢出不了 你虽然强制给他定义为9位, 但是一个int实际是32位, 会正常往前走
0000 0000 这个咋运算? 正常取反加1 ryxcaixia 发表于 2015-7-22 08:47
1 0000 0000 ;这是256的二进制;那么也就是原码了?最高位是1,判断是负数;
所有的数据在计算机中都以补 ...
谢谢 您这么耐心的给我解答,非常的感谢。昨天我有些钻牛角尖了。不好意思;:handshake lark 发表于 2015-7-22 17:18
谢谢 您这么耐心的给我解答,非常的感谢。昨天我有些钻牛角尖了。不好意思;
{:9_217:}{:9_217:}{:9_217:}{:9_217:}{:9_217:}{:9_217:}{:9_217:}
与君共勉 看看
~~~~~~~~~~~~~~~~~~~~·····:lol: lwmheaton 发表于 2015-7-24 11:57
看看
~~~~~~~~~~~~~~~~~~~~·····
:lol:
页:
[1]