对一个整形数右移32位整形会发生什么情况

1.&&&&&&目标:计算32位整形数内含有1的个数
2.&&&&&&最原本的思想:将整形数对应的32位二进制数字中所有的1加起来就是所求的结果。
7=00-00-+0+…+0+1+1+1=3
3.&&&&&&简化后的思想:逐次将相邻位的1相加,最后得到的总数就是要求的结果。
a)&&&&&&&&7=0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-1-1-1
=&7=00-00-00-00-00-00-00-00-00-00-00-00-00-00-01-10
注释:相邻2位相加,实际上是1位加1位,得到相邻2位1的总和,为了防止得到的值溢出,在保证和不变的同时,将1位加1位的和用2位表示,仍然放在原来的位置上,不过此时,相邻2位表示的是一个值,应看作一个整体。
b)&&&&&&&7=00-00-00-00-00-00-00-00-00-00-00-00-00-00-01-10
=&7=00-00-
&&& 注释:相邻4位相加(相邻2个值相加),实际上还是1个值加1个值,得到相邻
4位1的总和,为了防止溢出,将1个值(2位)加1个值(2位)的和变为4位,仍然放在原来的位置上,不过此时相邻4位看作一个值,表示原来相邻4位中1的总和,应看作一个整体。
c)&&&&&&&7=00-00-
注释:依次类推,相邻8位在原来4位的基础上相加,得到相邻8位1的总和,放在原来的位置上,不过此时相邻8位看作一个值,表示原来8位中1的总和,应看作一个整体参与下一次的运算中。
d)&&&&&&&7=00-
注释:依次类推,相邻16位在原来8位的基础上相加,得到相邻16位1的总和,放在原来的位置上,不过此时相邻16位看作一个值,表示原来16位中1的总和,应看作一个整体参与下一次的运算中。
e)&&&&&&&&7=
注释:依次类推,相邻32位在原来16位的基础上相加,得到相邻32位1的总和,放在原来的位置上,不过此时相邻32位看作一个值,表示原来32位中1的总和,应看作一个整体参与下一次的运算中。
4.&&&&&&利用掩码实现简化后的思想。
代码实现如下:
intCountBits(unsigned int x)
static unsigned int mask[] =
&&&&&&& 0x,
&&&&&&& 0x,
&&&&&&& 0x0f0f0f0f,
&&&&&&& 0x00ff00ff,
&&&&&&& 0x0000ffff
//计算循环次数以及取正确的掩码值
/*Number of positions to shift toright*///计算正确的右移位数,右移位数用于将高位移动到对应低位
for(i = 0, shift = 1; i& 5; i++,shift *= 2)
&&&&&&& printf(&i = %d& shift = %d&mask[i] = %d x=%d x&&shift = %d x= %d\n&,i,shift,mask[i],x,x&&shift,
&&&&&&&&&&&&&& (x & mask[i]) + ((x &&shift) & mask[i]));
&&&&&&& x = (x & mask[i]) + ((x &&shift) & mask[i]);
代码分析:
a)&&&&&&i//计算循环次数以及取正确的掩码值
shift//计算正确的右移位数,右移位数用于将高位移动到对应低位
&&&&&&&&&&&&& 循环0-4对应3中思想分析的a-e
&&&&&& 取x = 7;
&&&&&& 当i = 0,shift = 1 时,
x = 7=0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-1-1-1,
mask[0]=0x-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1-0-1
分析x = (x & mask[i]) + ((x && shift) & mask[i]);
x & mask[0]将相邻2位中的高位全部置0,而低位的有效位全部保留了下来。
x&&shift将x所有位右移一位,即将相邻2位中的高位全部移动到了低位的位置上,同时保证了高位的有效位没有损失。
(x&&shift)&mask[0]将移动后的低位,即原来相邻2位中的高位有效位全部保留下来了。
x = (x &mask[i]) + ((x && shift) & mask[i]);实现了相邻2位依次相加,并将值保留至原来相邻2位上的功能。
对应于3.a)
b)&&&&&当 i=1,shift = 1*2时,
x=7=00-00-00-00-00-00-00-00-00-00-00-00-00-00-01-10
&&&&&& mask[1]=0x-11-00-11-00-11-00-11-00-11-00-11-00-11-00-11
分析x = (x & mask[i]) + ((x && shift) & mask[i]);
与4.a)类似,实现了相邻4位依次相加,并将值保留至原来相邻4位上的功能。
对应于3.b)
c)&&&&&当i=2, shift = 1*2*2时,
x=7=00-00-
mask[2]=0x0f0f0f0f=00-11-
分析x = (x & mask[i]) + ((x && shift) & mask[i]);
与4.c)类似,实现了相邻8位依次相加,并将值保留至原来相邻8位上的功能。
对应于3.c)
d)&&&&&当i=3, shift = 1*2*2*2时,
mask[2]=0x00ff00ff=00-
分析x = (x & mask[i]) + ((x && shift) & mask[i]);
与4.d)类似,实现了相邻16位依次相加,并将值保留至原来相邻16位上的功能。
对应于3.d)
e)&&&&&&当i=4, shift = 1*2*2*2*2时,
mask[2]=0x0000ffff=
分析x = (x & mask[i]) + ((x && shift) & mask[i]);
与4.e)类似,实现了相邻32位依次相加,并将值保留至原来相32位上的功能。
对应于3.e)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:166次
排名:千里之外32位移位寄存器是什么来自:
日分享至 :
下一篇:上一篇:其它类似问题相关文章相关帖子--32位移位寄存器是什么C语言的移位操作符
- ITeye技术网站
位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对
象,第二个运算对象是所移的二进制位数。
  位移位运算符的运算对象、运算规则与结果、结合性如表2-16所示。
  移位时,移
出的位数全部丢弃,移出的空位补入的数与左移还是右移花接木有关。如果是左移,则规定补入的数全部是0;如果是右移,还与被移位的数据是否带符号有关。若
是不带符号数,则补入的数全部为0;若是带符号数,则补入的数全部等于原数的最左端位上的原数(即原符号位)。具体移位规则如下所示。
 位移位运算符的优先级如下:
   ·算术运算符 优先于 位移位运算符 优先于 关系运算符
   ·位移位运算符是同级别的,结合性是
  例如,设无符号短整型变量a为0111(对应二进制数为1001),
则:a&&3 结果为01110(对应二进制数为1000),a不变
     a&&4
结果为04 (对应二进制数为0100),a不变
  又如,设短整型变量a为-4(对应二进制数为
   则:a&&3
结果为-32(对应二进制数为0000),a不变
     a&&4
结果为-1(对应二进制数为1111),a不变
C语言里的左移和右移运算
先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用&&运算符.例如:
int i = 1;
i = i && 2;
//把i里的值左移2位
也就是说,1的2进制是000...0001(这里1前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成
0100,也就是10进制的4,所以说左移1位相当于乘以2,那么左移n位就是乘以2的n次方了(有符号数不完全适用,因为左移有可能导致符号变化,下面
需要注意的一个问题是int类型最左端的符号位和移位移出去的情况.我们知道,int是有符号的整形数,最左端的1位是符号位,即0正1负,那么移
位的时候就会出现溢出,例如:
int i = 0x; //16进制的,为2进制的...0000
那么,i在左移1位之后就会变成0x,也就是2进制的100000...0000,符号位被置1,其他位全是0,变成了int类型
所能表示的最小值,32位的int这个值是-,溢出.如果再接着把i左移1位会出现什么情况呢?在C语言中采用了丢弃最高位的处理方
法,丢弃了1之后,i的值变成了0.
左移里一个比较特殊的情况是当左移的位数超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位,如:
int i = 1, j = 0x; //设int为32位
i = i && 33;
% 32 = 1 左移1位,i变成2
j = j && 33;
// 33 % 32 = 1
左移1位,j变成0,最高位被丢弃
在用gcc编译这段程序的时候编译器会给出一个warning,说左移位数&=类型长度.那么实际上i,j移动的就是1位,也就是33%32
后的余数.在gcc下是这个规则,别的编译器是不是都一样现在还不清楚.
就是: 丢弃最高位,0补最低位
再说右移,明白了左移的道理,那么右移就比较好理解了.
右移的概念和左移相反,就是往右边挪动若干位,运算符是&&.
右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如:
int i = 0x;
i = i && 1;
//i的值不会变成0x,而会变成0xc0000000
就是说,符号位向右移动
后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.
负数 &&5(假设字长为8位),则得到的是
总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变
.实际应用中可以根据情况用左/右移做快速的乘
/除运算,这样会比循环效率高很多.
在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
操作符 作用
────────────────────────────
& 位逻辑与
| 位逻辑或
位逻辑异或
- 位逻辑反
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
按位运算是对字节或字中的实际位进行检测、设置或移位, 它只适用于字符型和整数型变量以及它们的变体,
对其它数据类型不适用。
我们要注意区分位运算和逻辑运算。
1. 按位与运算
按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1
,否则为0。参与运算的数以补码方式出现。
例如:9&5可写算式如下:
(9的二进制补码)&的二进制补码) 的二进制补码)可见9&5=1。
按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255
的二进制数为1111)。
int a=9,b=5,c;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
2. 按位或运算
按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补
例如:9|5可写算式如下: 00101
(十进制为13)可见9|5=13
a=9,b=5,c;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
3. 按位异或运算
按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如
9^5可写成算式如下: 00 (十进制为12)
printf("a=%d\n",a);
4. 求反运算 求反运算符~为单目运算符,具有右结合性。
其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(1001)结果为:0110
5. 左移运算
左移运算符“&&”是双目运算符。其功能把“&&
”左边的运算数的各二进位全部左移若干位,由“&&”右边的数指定移动的位数,高位丢弃,低位补0。例如: a&&4
指把a的各二进位向左移动4位。如a=(十进制3),左移4位后为(十进制48)。
6. 右移运算
右移运算符“&&”是双目运算符。其功能是把“&&
”左边的运算数的各二进位全部右移若干位,“&&”右边的数指定移动的位数。例如:设
a=15,a&&2 表示把右移为(十进制3)。应该说明的是,对于有符号数,在右移时,符号位将随同移
动。当为正数时, 最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。
unsigned a,b;
printf("input
a number: ");
scanf("%d",&a);
printf("a=%d\tb=%d\n",a,b);
char a='a',b='b';
int p,c,d;
p=(p&&8)|b;
c=(p&0xff00)&&8;
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
当进行按位与或时,最好使用16进制,在程序中这样表示:0x01
所以,字符类型a的最高位强制1可以这样:a=a|0x80。其他的可以依次类推!
Henry.cong
浏览: 120782 次
来自: 大连
其实java地重载是静态重载,本质就是定义了不同的方法,它在编 ...
厉害厉害,受教了,写得很详细,大牛}

我要回帖

更多关于 自体脂肪移植面部整形 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信