您的位置:首页 > 其它

位运算

2015-11-15 11:51 225 查看
</pre><span style="font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14px; line-height: 21px; orphans: 2; widows: 2;">6种位运算</span><p style="margin-top: 5px; margin-bottom: 5px; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14px; line-height: 21px; orphans: 2; widows: 2;">& (<span style="font-size: 10.5pt; line-height: 1.5;">位与</span><span style="font-size: 10.5pt; line-height: 1.5;">) , </span><span style="font-size: 10.5pt; line-height: 1.5;">| (</span><span style="font-size: 10.5pt; line-height: 1.5;"> 位或</span><span style="font-size: 10.5pt; line-height: 1.5;">) </span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14px; line-height: 21px; orphans: 2; widows: 2;"><span style="font-size: 10.5pt; line-height: 1.5;">~  (</span><span style="font-size: 10.5pt; line-height: 1.5;">位反</span><span style="font-size: 10.5pt; line-height: 1.5;">) , </span><span style="font-size: 10.5pt; line-height: 1.5;">^  (</span><span style="font-size: 10.5pt; line-height: 1.5;">异或</span><span style="font-size: 10.5pt; line-height: 1.5;">)</span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14px; line-height: 21px; orphans: 2; widows: 2;"><span style="font-size: 10.5pt; line-height: 1.5;">>> (</span><span style="font-size: 10.5pt; line-height: 1.5;">右移</span><span style="font-size: 10.5pt; line-height: 1.5;">)</span><span style="font-size: 10.5pt; line-height: 1.5;">,<< (</span><span style="font-size: 10.5pt; line-height: 1.5;">左移</span><span style="font-size: 10.5pt; line-height: 1.5;">)</span></p><span style="font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 10.5pt; line-height: 1.5; orphans: 2; widows: 2;"></span><span style="font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 10.5pt; line-height: 1.5; orphans: 2; widows: 2;"></span><p style="margin-top: 5px; margin-bottom: 5px; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei', Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14px; line-height: 21px; orphans: 2; widows: 2;"><strong>1,& 位与</strong></p><p><pre name="code" class="cpp">#include <stdio.h>
#include <stdint.h>
int main() {
/**
* & 位与运算
* 对比两个二进制数据的位,如果对应的位数均为1则结果为1,否则为0
*/
int a = 0b1001;
int b = 0b1010;
printf("%d\n",a & b);  //位与 运算后的二进制结果为 0b1000  所以输出的十进制结果为8
int8_t c = 20;  //对应8位的二进制为 0001 0100
int8_t d = 30;  //对应8位的二进制为 0001 1110
printf("%d\n",d & c);  //位与 运算后的二进制结果为 0001 0100  所以输出的十进制结果为20
}


2,| 位或
#include <stdio.h>

#include <stdint.h>


int main() {

   /**

    * | 位或运算

    * 对比两个二进制数据的位,如果对应的位数均为0则结果为0,否则为1

    */

   int a = 0b1001;

   int b = 0b1010;

   printf("%d\n",a | b);  //位或 运算后的二进制结果为 0b1011  所以输出的十进制结果为11

   int8_t c = 20;  //对应8位的二进制为 0001 0100

   int8_t d = 30;  //对应8位的二进制为 0001 1110

   printf("%d\n",d | c);  //位或 运算后的二进制结果为 0001 1110  所以输出的十进制结果为30

}


3,~ 位反
#include <stdio.h>

#include <stdint.h>


int main() {



   /**

    * ~ 位反运算

    * 对二进制数据进行取反,1变成0、0变成1

    *

    *

    * 假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:

    * 00000000 00000000 00000000 00000101

    * 5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

    *

    * 现在想知道,-5在计算机中如何表示?

    * 在计算机中,负数以其正值的补码形式表达。

    * 什么叫补码呢?这得从原码,反码说起。

    *

    * 原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

    * 比如 00000000 00000000 00000000 00000101 是 5的 原码。

    *

    * 反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

    * 取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)

    * 比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。

    * 称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码,反码是相互的

    *

    * 补码:反码加1称为补码。

    * 也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。

    * 比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。

    * 那么,补码为:11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011

    */


   int8_t a = 3; //3对应8位的二进制数据为 0000 0011

   a = ~a;       //3位返 运算后的结果为   1111 1101

   printf("%d\n",a);  //输出结果为-4


   uint8_t b = 5;     //无符号的最大储值是255

   b = ~b;            //无符号的5位返后的值为 255 - 5 = 250

   printf("%d\n",b);  //结果为250 无符号的int位反后的值为最大储值减要位反的值

}


4,^ 异或

#include <stdio.h>

#include <stdint.h>


int main() {

   /**

    * ^ 异或

    * 对比两个二进制数据的位,如果对应的位数不相同则为1,否则为0

    */


   int8_t a=0b0001;

   int8_t b=0b0011;

   printf("%d\n", a^b);  //异或运算后的结果为0b0010、输出结果为2

   return 0;

}


5,<< 左移
#include <stdio.h>


int main() {

   /**

   * << 左移

   * 示例:

   *      2 << 1 = 4   // 0b0010 左移一位后的结果为 0b0100

   * 将二进制数向左移位、移位后右边用0填充

   * * 向左移一位后的值,刚好为原值乘2。

   * 用这种移位的方式作乘法运算是最快的

   */

   printf("%d\n", 5<<1);  //0b0101移一位为0b1010 结果为10 类似 5*2

   printf("%d\n", 5<<2);  //0b0101移二位为0b10100 结果为20 类似 5*2*2

   printf("%d\n", 5<<3);  //0b0101移三位为0b101000 结果为40 类似 5*2*2*2

   printf("%d\n", 5<<4);  //0b0101移四位为0b1010000 结果为80 类似 5*2*2*2*2

   return 0;

}


6,>> 右移

#include <stdio.h>


int main() {

   /**

   * >> 右移

   * 示例:

   *      2 >> 1 = 1   // 0b0010 左移一位后的结果为 0b0001

   * 和左移位相反将二进制数向右移位

   */

   printf("%d\n", 5>>1);  //0b0101移一位为0b0010 结果为2

   printf("%d\n", 5>>2);  //0b0101移二位为0b0001 结果为1

   printf("%d\n", 5>>3);  //0b0101移三位为0b0000 结果为0

   printf("%d\n", 5>>4);  //0b0101移四位为0b0000 结果为0

   printf("%d\n", 6>>1);  //0b0110移一位为0b0011 结果为3

   return 0;

}


7,示例-使用位运算提取颜色通道值

#include <stdio.h>

#include <stdint.h>

int main() {

   /**

    * 通常用十六进制保存颜色值

    * 0xFFEEDDCC 每两位一个通道,四个通道分别表示 ARGB(Alpha,Red,Greed,Blue)

    * 可以通过红绿蓝及透明度混合成任何一种颜色

    */

   uint32_t color = 0xFFEEDDCC;


   /**

    * 现在要通要取红色通道的值

    * 首先用位与运算去掉其它通道的值

    * 0b11111111 11101110 11011101 11001100   //color值

    * 0b00000000 11101110 00000000 00000000   //位与0x00FF0000后的值

    */

   uint32_t temp = color & 0x00FF0000;


   //再将0b00000000 11101110 00000000 00000000右移16位所得的即为红色通道的值

   uint8_t red=temp>>16;  //红色通道EE,结果输出238

   printf("%d\n", red);

   return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息