Javascript 什么是位运算符?

Javascript 什么是位运算符?,javascript,boolean,bitwise-operators,boolean-logic,Javascript,Boolean,Bitwise Operators,Boolean Logic,我是一个只为好玩而编写代码的人,在学术或专业环境中都没有真正深入研究过,所以像这些位运算符这样的东西我真的不知道 我在读一篇关于JavaScript的文章,它显然支持按位操作。我一直在一些地方看到有人提到过这个手术,我也试着读一些关于它的文章,想弄清楚它到底是什么,但我似乎一点也不明白。那么它们是什么呢?清晰的例子会很好D 还有几个问题-位运算的一些实际应用是什么?您什么时候可以使用它们?这些是按位运算符,在JavaScript中都受支持: op1&op2——与运算符比较两个位,如果两个位都是

我是一个只为好玩而编写代码的人,在学术或专业环境中都没有真正深入研究过,所以像这些位运算符这样的东西我真的不知道

我在读一篇关于JavaScript的文章,它显然支持按位操作。我一直在一些地方看到有人提到过这个手术,我也试着读一些关于它的文章,想弄清楚它到底是什么,但我似乎一点也不明白。那么它们是什么呢?清晰的例子会很好D


还有几个问题-位运算的一些实际应用是什么?您什么时候可以使用它们?

这些是按位运算符,在JavaScript中都受支持:

  • op1&op2
    ——与运算符比较两个位,如果两个位都是1,则生成结果1;否则,它返回0

  • op1 | op2
    -
    运算符比较两个位,如果两个位是互补的,则生成结果1;否则,它返回0

  • op1^op2
    -
    EXCLUSIVE-OR
    运算符比较两位,如果其中一位为1,则返回1;如果两位均为0或1,则返回0

  • ~op1
    -
    补码
    运算符用于反转操作数的所有位

  • op1>op2
    -
    SHIFT RIGHT
    运算符将位向右移动,丢弃最右边的位,并将最左边的位赋值为0。每次向右移动都会将op1有效地分成两半。保留最左侧的符号位

  • op1>>>op2
    -
    向右移位
    -
    零填充
    运算符将位向右移动,丢弃最右边的位,并将最左边的位赋值为0。每次向右移动都会将op1有效地分成两半。最左边的符号位被丢弃


  • 逐位运算符是一次处理一位的运算符

    仅当其两个输入均为1时,AND才为1

    如果一个或多个输入为1,则为1

    只有当XOR的一个输入正好为1时,XOR才为1

    NOT仅当其输入为0时才为1

    这些可以最好地描述为真值表。输入可能性在顶部和左侧,结果位是两个输入的交点处显示的四个值之一(非的情况下为两个,因为它只有一个输入)

    AND|0 1      OR|0 1
    ---+----    ---+----
      0|0 0       0|0 1
      1|0 1       1|1 1
    
    XOR|0 1     NOT|0 1
    ---+----    ---+---
      0|0 1        |1 0
      1|1 0
    
    一个例子是,如果您只需要整数的低位4位,则可以使用15(二进制1111)将其与之相加,因此:


    值得注意的是,作为其他答案列出的单位真值表一次只能处理一个或两个输入位。使用整数时会发生什么情况,例如:

    int x = 5 & 6;
    
    答案在于每个输入的二进制扩展:

      5 = 0 0 0 0 0 1 0 1
    & 6 = 0 0 0 0 0 1 1 0
    ---------------------
          0 0 0 0 0 1 0 0
    
    每列中的每对位都通过“AND”函数运行,以在底线上给出相应的输出位。所以上面表达式的答案是4。CPU(在本例中)并行地完成了8个独立的“和”操作,每列一个


    我之所以提到这一点,是因为我仍然记得很多年前当我了解到这一点时,有一个“啊哈!”的时刻。

    更详细地说,它与所讨论的值的二进制表示有很大关系

    For example (in decimal): x = 8 y = 1 would come out to (in binary): x = 1000 y = 0001 From there, you can do computational operations such as 'and' or 'or'; in this case: x | y = 1000 0001 | ------ 1001 or...9 in decimal 例如(十进制): x=8 y=1 将显示为(二进制): x=1000 y=0001 从那里,你可以进行诸如“and”或“or”之类的计算操作;在这种情况下: x | y= 1000 0001 | ------ 1001 或…十进制9 希望这有帮助

    当提到术语“按位”时,有时会澄清is不是“逻辑”运算符

    例如,在JavaScript中;同时,但可以处理非布尔类型

    以expr1和expr2为例

    如果可以转换,则返回expr1 虚假;否则,返回expr2。 因此,当与布尔值一起使用时, &&如果两个操作数均为空,则返回true 是的;否则,返回false

    正如其他人所指出的,2&4是位AND,因此它将返回0

    您可以将以下内容复制到test.html或其他内容并进行测试:

    <html>
    <body>
    <script>
        alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
            + "2 && 4 = " + (2 && 4) + "\n"
            + "2 & 4 = " + (2 & 4));
    </script>
    
    
    警报(“猫”和“狗”=“+(“猫”和“狗”)+”\n
    +“2&&4=“+(2&&4)+”\n”
    + "2 & 4 = " + (2 & 4));
    
    因为没有人提出为什么这些有用的问题:

    在处理标志时,我经常使用位操作。例如,如果要将一系列标志传递给操作(例如,
    File.Open()
    ,同时启用读取模式和写入模式),则可以将它们作为单个值传递。这是通过将每个可能的标志分配到位集中自己的位(字节、短、int或长)来实现的。例如:

     Read: 00000001
    Write: 00000010
    
    因此,如果你想通过读和写,你需要通过(读|写),然后将两者结合成一个函数

    00000011
    
    然后可以在另一端解密,如:

    if ((flag & Read) != 0) { //...
    
    哪个检查

    00000011 &
    00000001
    
    返回

    00000001
    
    它不是0,因此该标志不指定读取

    您可以使用XOR来切换各种位。我在使用标志指定方向输入(上、下、左、右)时使用了此选项。例如,如果一个精灵正在水平移动,并且我希望它旋转:

         Up: 00000001
       Down: 00000010
       Left: 00000100
      Right: 00001000
    Current: 00000100
    
    我只是用(LEFT | RIGHT)对当前值进行异或运算,在本例中,它将关闭LEFT,打开RIGHT

    在几种情况下,位移位是有用的

    x << y
    
    颜色通常以这种方式存储(最高有效字节被忽略或用作Alpha):

    要再次找到值,只需将位向右移动,直到它位于底部,然后屏蔽剩余的高阶位:

    Int Alpha = Color >> 24
    Int Red = Color >> 16 & 0xFF
    Int Green = Color >> 8 & 0xFF
    Int Blue = Color & 0xFF
    
    0xFF
    11111111
    相同。所以基本上,对于红色,你应该这样做:

    Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
    00000000 00000000 11111111 00010101 &
    00000000 00000000 00000000 11111111 =
    00000000 00000000 00000000 00010101 (The original value)
    

    我一直听说JavaScript逐位运算符有多慢。我做了一些测试,发现在一些测试中,它们比算术选项快40%到80%。也许他们过去很慢。在现代浏览器中,我喜欢它们

    我的代码中有一个案例可以更快、更容易地进行r
    int val = (A << 24) | (B << 16) | (C << 8) | D;
    
    A = 01000000
    B = 00000101
    C = 00101011
    D = 11100011
    val = 01000000 00000101 00101011 11100011
    
    A = 255 = 11111111
    R = 21 = 00010101
    G = 255 = 11111111
    B = 0 = 00000000
    Color = 11111111 00010101 11111111 00000000
    
    Int Alpha = Color >> 24
    Int Red = Color >> 16 & 0xFF
    Int Green = Color >> 8 & 0xFF
    Int Blue = Color & 0xFF
    
    Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
    00000000 00000000 11111111 00010101 &
    00000000 00000000 00000000 11111111 =
    00000000 00000000 00000000 00010101 (The original value)
    
             5: 00000101
             3: 00000011
    
        AND|0 1        OR|0 1 
        ---+----      ---+---- 
          0|0 0         0|0 1 
          1|0 1         1|1 1 
    
       XOR|0 1        NOT|0 1 
       ---+----       ---+--- 
         0|0 1           |1 0 
         1|1 0
    
        203: 1100 1011
    AND  15: 0000 1111
    ------------------
      =  11: 0000 1011
    
    int main()
    {
         int x = 19;
         printf ("x << 1 = %d\n" , x <<1);
         printf ("x >> 1 = %d\n", x >>1);
         return 0;
    }
    // Output: 38 9
    
    int main()
    {
        int x = 19;
        (x & 1)? printf("Odd"): printf("Even");
        return 0;
     }
    // Output: Odd
    
    int min(int x, int y)
    {
        return y ^ ((x ^ y) & - (x < y))
    }
    
    #include <stdio.h>
    int main ()
    {
        int n , c , k ;
        printf("Enter an integer in decimal number system\n " ) ;
        scanf( "%d" , & n );
        printf("%d in binary number
        system is: \n " , n ) ;
        for ( c = 31; c >= 0 ; c -- )
        {
             k = n >> c ;
             if ( k & 1 )
                  printf("1" ) ;
             else
                  printf("0" ) ;
          }
          printf(" \n " );
          return 0 ;
    }