7.7位操作

7.7.1位段。

在struct中,对于int或unsigned int类型。使用 int i:5;的形式,确定该成员位数大小。

1.大小不能超过该位段类型大小。位段在内存中具体储存形式由具体编译器决定。

2.当前位段不能放在一个存储单元时(该存储单元特指位段类型大小,int,unsigned int也就是4字节),会将当前存储单元剩余空间闲置,从下一个存储单元开始。

struct A{

  int a:2;

  int b:  29;

   int c:1 

};

sizeof(A)是4字节,如果b位段是30位,就是8字节。如果b位段是32位,就是12字节。

位段在同一存储单元里的紧凑的,可以定义无名字段,是为了分隔空位,不使用所对应的位。

A t;  t.a=1;  t.c=1; cout<<t.a<<t.c; 结果是1,-1.因为存储的是01,1转换成int时,位扩展,01扩展为00000000000000000001,1被当成负数,扩展为1111111111111111.


7.7.2如何快速得到一个数的7倍

移位操作,(X<<3)-X


7.7.3 用位操作实现求平均数

(x&y+(x^y>>1));都为1的不用除2,单独为1的除2

这种方法可以保证不溢出。

引申:求一个数的绝对值。

对于整数x,x>>31。x为正数,结果是0x00000000,x为负数,结果是0xffffffff。

y=x>>31;

x的绝对值等于 x^y-y;

x^0x00000000不变。

x^0xffffffff是按位取反(包括符号位),再加1,相当于进行反码操做+1.


7.7.4注意补码。

32位机器。取值范围0-4294927695. int的是-2147483647~2147483647


7.7.5判断一个整数的1的个数

使用x&(x-1);

while(x)  count++;  x&=x-1;

x-1按位来看,是使最右为1的位变成0;

注意0x1u,指的是16位无符号数1.


7.7.6 不用sizeof判断系统是32位还是16位。

对unsigned int a=~0判断。0取反后得到最大值。

16位表示最大值65535,如果a>65536.则是32位的。


7.7.7大端和小端

小端模式cpu对操作数的存储从低字节向高字节存。小端模式先存34,再存12.

大端模式cpu从高字节向低字节存。如0x1234,大端模式先存12,再存34.

x86为小端模式,单片机一般为大端模式。

注意 0的ASCII码是48,A是65,a是97

判断模式可以使用截断的方法,如用short int a=0x1234;char b=a;b==0x12就是大端,是0x34就是小端。


7.78 n位2进制数,有多少个数中不存两个相邻的1.

1.斐波拉契数列,a[n]=a[n-1]+a[n-2],a[1]=a[2]=初值。

int F(int i){

  if(i==1)

     return 2;

  if(i==2)

    return 3;

  return F(i-1)+F(i-2);

}

2.递推

int F(int i){

 if(i==1)

     return 2;

  if(i==2)

    return 3;

   int n1=2;

   int n2=3;

  for(int n=n1+n2;i>3;i--)

       n1=n2;

      n2=n;

     n=n1+n2;

}


7.7.9关于位运算的知识

这个后续补充,比较重要















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值