鱼C论坛

 找回密码
 立即注册
查看: 1609|回复: 11

位域/位段/bit field :输入+256,打印-256,请教原因

[复制链接]
发表于 2015-7-20 07:14:58 | 显示全部楼层 |阅读模式
5鱼币
进制 位域 相关的的问题;
插入代码(问题在注释里面):
#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;

最佳答案

查看完整内容

楼主 计算机组成原理里层曰 : 在计算机中, 无论正数还是负数都一律采取补码表示 正数的补码还是自己, 负数的补码则是取反加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 取反(因为是负数) 就是 0x ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-20 07:14:59 | 显示全部楼层
本帖最后由 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;
然后打印出来
1.png

如图所示, char 和unsign char 都是8位一个字节
不同的是最高位是否为符号位
有符号的就代表为-1(取反后再减1 过程刚好逆过来)
无符号的就代表255
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-20 11:38:01 | 显示全部楼层
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;                
}

再添加一段代码 这段代码可以打印出变量在内存中的真实形状
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-20 11:57:55 | 显示全部楼层
ryxcaixia 发表于 2015-7-20 07:14
楼主 计算机组成原理里层曰 : 在计算机中, 无论正数还是负数都一律采取补码表示
正数的补码还是自己, 负 ...

非常感谢,你又一次帮我解决问题了。谢谢:handshake
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-21 17:00:57 | 显示全部楼层
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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-21 17:12:42 | 显示全部楼层
本帖最后由 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-21 17:49:22 | 显示全部楼层
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;(补码,那个问号表示后面怎么算,当溢出遇见符号位时)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-22 08:47:23 | 显示全部楼层
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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-22 17:18:28 | 显示全部楼层
ryxcaixia 发表于 2015-7-22 08:47
1 0000 0000 ;这是256的二进制;那么也就是原码了?最高位是1,判断是负数;
所有的数据在计算机中都以补 ...

谢谢 您这么耐心的给我解答,非常的感谢。昨天我有些钻牛角尖了。不好意思;:handshake
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-22 17:50:57 | 显示全部楼层
lark 发表于 2015-7-22 17:18
谢谢 您这么耐心的给我解答,非常的感谢。昨天我有些钻牛角尖了。不好意思;




与君共勉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-24 11:57:10 | 显示全部楼层
看看
~~~~~~~~~~~~~~~~~~~~·····:lol:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-24 15:13:32 | 显示全部楼层
lwmheaton 发表于 2015-7-24 11:57
看看
~~~~~~~~~~~~~~~~~~~~·····

:lol:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-26 05:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表