zoukankan      html  css  js  c++  java
  • C 位与运算

    位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作

    运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
    C语言提供的位运算符列表:
    运算符 含义 描述
    & 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
    | 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
    ^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
    ~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
    << 左移 用来将一个数的各二进制位全部左移N位,右补0
    >> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0

    1、“按位与”运算符(&)

        按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1,

    则该位的结果值为1;否则为0。这里的1可以理解为逻辑中的true,0可以理解为逻辑中的false。按位与其

    实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才为真。若,

    A=true,B=true,则A∩B=true 例如:3&5 3的二进制编码是11(2)。(为了区分十进制和其他进制,本文规

    定,凡是非十进制的数据均在数据后面加上括号,括号中注明其进制,二进制则标记为2)内存储存数据

    的基本单位是字节(Byte),一个字节由8个位(bit)所组成。位是用以描述电脑数据量的最小单位。二

    进制系统中,每个0或1就是一个位。将11(2)补足成一个字节,则是00000011(2)。5的二进制编码是

    101(2),将其补足成一个字节,则是00000101(2)
    按位与运算:
     00000011(2)
    &00000101(2)
     00000001(2)
    由此可知3&5=1
    c语言代码:
    #include <stdio.h>
    main()
    {
     int a=3;
     int b = 5;
     printf("%d",a&b);
    }
    按位与的用途:
    (1)清零
    若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:

    原来的数中为1的位,新数中相应位为0。然后使二者进行&运算,即可达到清零目的。
    例:原数为43,即00101011(2),另找一个数,设它为148,即10010100(2),将两者按位与运算:
     00101011(2)
    &10010100(2)
     00000000(2)
    c语言源代码:
    #include <stdio.h>
    main()
    {
     int a=43;
     int b = 148;
     printf("%d",a&b);
    }
    (2)取一个数中某些指定位
    若有一个整数a(2byte),想要取其中的低字节,只需要将a与8个1按位与即可。
    a 00101100 10101100
    b 00000000 11111111
    c 00000000 10101100
    (3)保留指定位:
    与一个数进行“按位与”运算,此数在该位取1.
    例如:有一数84,即01010100(2),想把其中从左边算起的第3,4,5,7,8位保留下来,运算如下:
     01010100(2)
    &00111011(2)
     00010000(2)
    即:a=84,b=59
        c=a&b=16
    c语言源代码:
    #include <stdio.h>
    main()
    {
     int a=84;
     int b = 59;
     printf("%d",a&b);
    }

    2、“按位或”运算符(|)
    两个相应的二进制位中只要有一个为1,该位的结果值为1。借用逻辑学中或运算的话来说就是,一真为真


    例如:60(8)|17(8),将八进制60与八进制17进行按位或运算。
     00110000
    |00001111
     00111111 
    c语言源代码:
    #include <stdio.h>
    main()
    {
     int a=060;
     int b = 017;
     printf("%d",a|b);
    }
    应用:按位或运算常用来对一个数据的某些位定值为1。例如:如果想使一个数a的低4位改为1,则只需要

    将a与17(8)进行按位或运算即可。

    3、“异或”运算符(^)
    他的规则是:若参加运算的两个二进制位值相同则为0,否则为1
    即0∧0=0,0∧1=1,1∧0=1, 1∧1=0
        例:   00111001
            ∧ 00101010
               00010011 
    c语言源代码:
    #include <stdio.h>
    main()
    {
     int a=071;
     int b = 052;
     printf("%d",a^b);
    }
    应用:
    (1)使特定位翻转
    设有数01111010(2),想使其低4位翻转,即1变0,0变1.可以将其与00001111(2)进行“异或”运算,

    即:
     01111010
    ^00001111
     01110101
    运算结果的低4位正好是原数低4位的翻转。可见,要使哪几位翻转就将与其进行∧运算的该几位置为1

    即可。
    (2)与0相“异或”,保留原值
    例如:012^00=012
            00001010
           ^00000000
            00001010
    因为原数中的1与0进行异或运算得1,0^0得0,故保留原数。
    (3) 交换两个值,不用临时变量
    例如:a=3,即11(2);b=4,即100(2)。
    想将a和b的值互换,可以用以下赋值语句实现:
        a=a∧b;
        b=b∧a;
        a=a∧b;
    a=011(2)
        (∧)b=100(2)
    a=111(2)(a∧b的结果,a已变成7)
        (∧)b=100(2)
    b=011(2)(b∧a的结果,b已变成3)
        (∧)a=111(2)


    a=100(2)(a∧b的结果,a已变成4)
    等效于以下两步:
        ① 执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。
        ② 再执行第三个赋值语句: a=a∧b。由于a的值等于(a∧b),b的值等于(b∧a∧b),

    因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。
    很神奇吧!
    c语言源代码:
    #include <stdio.h>
    main()
    {
     int a=3;
     int b = 4;
     a=a^b;
     b=b^a;
     a=a^b;
     printf("a=%d b=%d",a,b);
    }

    4、“取反”运算符(~)
    他是一元运算符,用于求整数的二进制反码,即分别将操作数各二进制位上的1变为0,0变为1。
    例如:~77(8)
    源代码:
    #include <stdio.h>
    main()
    {
     int a=077;
     printf("%d",~a);
    }

    5、左移运算符(<<)
    左移运算符是用来将一个数的各二进制位左移若干位,移动的位数由右操作数指定(右操作数必须是非负

    值),其右边空出的位用0填补,高位左移溢出则舍弃该高位。
    例如:将a的二进制数左移2位,右边空出的位补0,左边溢出的位舍弃。若a=15,即00001111(2),左移2

    位得00111100(2)。
    源代码:
    #include <stdio.h>
    main()
    {
     int a=15;
     printf("%d",a<<2);
    }
    左移1位相当于该数乘以2,左移2位相当于该数乘以2*2=4,15<<2=60,即乘了4。但此结论只适用于该

    数左移时被溢出舍弃的高位中不包含1的情况。
        假设以一个字节(8位)存一个整数,若a为无符号整型变量,则a=64时,左移一位时溢出的是0

    ,而左移2位时,溢出的高位中包含1。

    6、右移运算符(>>)
    右移运算符是用来将一个数的各二进制位右移若干位,移动的位数由右操作数指定(右操作数必须是非负

    值),移到右端的低位被舍弃,对于无符号数,高位补0。对于有符号数,某些机器将对左边空出的部分

    用符号位填补(即“算术移位”),而另一些机器则对左边空出的部分用0填补(即“逻辑移位”)。注

    意:对无符号数,右移时左边高位移入0;对于有符号的值,如果原来符号位为0(该数为正),则左边也是移

    入0。如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,有的

    系统移入1。移入0的称为“逻辑移位”,即简单移位;移入1的称为“算术移位”。 
    例: a的值是八进制数113755: 
       a:1001011111101101 (用二进制形式表示)
       a>>1: 0100101111110110 (逻辑右移时)
       a>>1: 1100101111110110 (算术右移时)
       在有些系统中,a>>1得八进制数045766,而在另一些系统上可能得到的是145766。Turbo C和其他一些C

    编译采用的是算术右移,即对有符号数右移时,如果符号位原来为1,左面移入高位的是1。
    源代码:
    #include <stdio.h>
    main()
    {
     int a=0113755;
     printf("%d",a>>1);
    }

    7、位运算赋值运算符

    位运算符与赋值运算符可以组成复合赋值运算符。
       例如: &=, |=, >>=, <<=, ∧=
       例:  a & = b相当于 a = a & b
             a << =2相当于a = a << 2

  • 相关阅读:
    hive与hbase整合
    待重写
    hive DML
    【知识强化】第六章 总线 6.1 总线概述
    【知识强化】第五章 中央处理器 5.1 CPU的功能和基本结构
    【知识强化】第四章 指令系统 4.3 CISC和RISC的基本概念
    【知识强化】第四章 指令系统 4.2 指令寻址方式
    【知识强化】第四章 指令系统 4.1 指令格式
    【知识强化】第三章 存储系统 3.6 高速缓冲存储器
    【知识强化】第三章 存储系统 3.5 双口RAM和多模块存储器
  • 原文地址:https://www.cnblogs.com/MervynSG/p/5674715.html
Copyright © 2011-2022 走看看