关于整数在内存中的二进制存储方式,打印一个整数的二进制的几种方式

32位系统sizeof(int)=4,也就是有32位二进制数,内存中是以32位二进制补码的形式存放这个数的,int为有符号数,最前面一个数字是符号位,0表示正数,1表示负数。

也就是31位存储这个数的大小。

正数的补码就是他的原码本身,也就是num%2  ,余数倒叙排列,不够32位的前面补0,

例如,

00000000 00000000 00000000 00000001   表示1,

00000000 00000000 00000011 00000000   表示的是2的9次方+2的8次方=768。

最大int 

01111111 11111111 11111111 11111111   表示2的31次方-1=2147483647

负数的补码是他对应正数的原码的反码,再+1得到的。

如-1,对应的1的原码 

00000000 00000000 00000000 00000001

1的反码    

11111111 11111111 11111111 11111110

反码加1为           

11111111 11111111 11111111 11111111   这也就是内存中-1的存储方式。

int表示的最大正整数2147483647对应的负数-2147483647的二进制为

2147483647原码        

01111111 11111111 11111111 11111111

 反码    

10000000 00000000 00000000 00000000

反码+1       

10000000 00000000 00000000 00000001

那么int表示的最小的负数也就是 

10000000 00000000 00000000 00000000  也就是 -2147483648

知道原理了如何打印一个数的32位二进制码呢?

1,先用原始的取余倒序排列,设要打印的数位num,

对于正数,num%2的值也就是第32位,(num/2)%2取余也就是第31位,((num/2)/2)%2也就是第30位……

定义一个有32个元素的数组a[32]来存放余数,用一个for循环来将余数赋给数组,

for (i=0;i<32;i++ )

{

a[i]=num%2;

num/=2;

}

a[0]存放第32位,a[1]存放第31位 ,  a[2]存放第30位……   打印只要用下面语句倒序打印数组a,就可以了。a[31]a[30].......a[1]a[0]

for (j=31;j>=0;j--)

printf ( "%d",a[j] );

对于负数,他的存储方式也可以看做是,对应正数减去1之后的反码,如-1对应的正数1 减去1也就是0,

0的原码 

00000000 00000000 00000000 00000000

   反码    

11111111 11111111 11111111 11111111  也就是-1的存储方式

if(num<0)

{

num = -num-1;

for (i=31;i>=0;i-- )

{

a[i]=num%2;

num/=2;

}

}

这里我改变了一下赋值顺序,先将正整数第32位赋给a[31]……也就是a[0]存放第一位,打印的时候顺序打印数组就可以了(对于正数)。我们最终是要打印负数的二进制表示,所以还要取反,可以用下面的语句。

for (j=0;j<32;j++)

b[i] = (a[i]+1)%2;

那么,顺序打印数组b就可以了。

以下是这种方法的实验图:




2 用位操作打印。

用位的左移右移,我们可以将其他位都置0,

如  10100000 00001100 00000000 00000000我们左移2位再右移31位,就可以直接得到

      00000000 00000000 00000000 00000001       也就是上面的第2个1移到了最后一位,可以得到第30位的值

每一位都如此操作,我们就可以得到每一位的值0或1,依次打印即可。

 但是对于一个有符号的数,位的操作会使符号一起移动,但是如果符号位为1,你右移之后,符号位会自动补1,

如10000000 00001111 11110000 00001111  ,我们为了得到第1位的1,直接右移31位,我们预想的结果是

    00000000 00000000 00000000 00000001 ,但实际上,由于符号位为1,每次右移符号位都会自动补1,右移1位

    11000000 00000000 00000000 00000000,右移31位之后会变成

    11111111 11111111 11111111 11111111。

为了得到想要的结果,我们可以把int赋值给一个unsigned int,这样,就可以用这个方法了。



可以看到,我用了3种位操作的方法来打印,第3种是我上面讲的,

第2种也是转换为无符号数,进行了一次位操作;

第1种是在不转换为无符号数的情况下,进行位操作打印。结果都是正确的。


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值