有关c语言不同位数进行位运算的问题

如果要将一个特定的整型数a的bit15清0,其他位不变

a&=~(1<<15);

 

a&=0x3f<<3;
a>>=3;

 

如果要求a的bit3~bit8的对应整数

 

问题是:在第一个&运算中,a从bit16开始的后面高位应该是被保留了  

而在第二个运算中为什么a从bit8开始的高位不被保留?

提问可能没提清楚,简单点讲就是  我想知道不同长度进行位运算是如何进行的  为什么上面两种情况截然不同

你的意思的想知道二进制数怎么个左右移法是吧,安排,给你整的明明白白的。

就按你给的这两行代码:

a&=~(1<<15)等价于:

a=a&~(1<<15)

这行代码优先级最高的是括号里的,我们知道整型变量一般是占4个字节,一个字节有八位,所以4x8=32位。

首先<<是左移符哈,箭头朝那边就往那边移。

那么1<<15是怎么个移法,请看:

1是整型数,占四个字节,在计算机内是以二进制数存储,且是以补码的形式存储,而1是正数,正数的原码=补码=反码

所以1的补码是:00000000 00000000 00000000 00000001

总共32位,那么1<<15就是从1的二进制补码左边第一个开始数,数15个,移多少位就数多少位,这15个数全部拿走,再在1的二进制补码的末尾补15个0就是1<<15了。左移完就是:

0 00000000 00000001 00000000 0000000

之后~(1<<15)的 ~ 表示按位取反,就是每一位都取反,取反后的二进制数:1 11111111 11111110 11111111 1111111

然后a&~(1<<15)的 & 表示取反后的这个二进制数与你给定的整型数a按位与,与的话学过数电都知道,只有1和1与才是1,0和1,0和0与都是0.这就是左移的具体移法。最后给你总结一下:对于左移,不管是正数还是负数左移统统在末尾补0,移多少补多少个0.对于右移,区分正负数,正数的话在高位补0,移多少补多少,但是负数,先要求出负数在计算机中的补码,之后在右移,但这时候不是在最高位补0了,而是补1了,也是移多少补多少,举个例子-10>>3,-10右移3位,

-10的原码:10000000 00000000 00000000 00001010

-10的反码:11111111 11111111 11111111 11110101

-10的补码:11111111 11111111 11111111 11110110

右移三位,最右边三个拿走,在高位补1:

-10>>3   :111 11111111 11111111 11111111 11110

因为这是补码,补码的补码等于实际的原码,所以

            100 00000000 00000000 00000000 00001

            100 00000000 00000000 00000000 00010

所以-10>>3后的数字其实是-2,你可以打印试试,左右移就是这么移的。

null

第二个代码段是求a的bit3~bit8对应整数。。我明明打了这些字了他不上去

a&=~(1<<15);

转换为

a=a&(~(1<<15));

*****************************

a&=0x3f<<3;

转换为

a=a&(0x3f<<3);

**********************************

a>>=3;

转换为

a=a>>3;