什么是按位运算符?

问题描述 投票:122回答:9

我是一个只是为了好玩而编写代码的人,并没有在学术或专业环境中深入研究它,所以像这些按位运算符这样的东西真的让我感到厌烦。

我正在阅读一篇关于JavaScript的文章,它显然支持按位操作。我一直看到这个地方提到的这个操作,我试着去弄清楚究竟是什么,但我似乎根本没有得到它。那他们是什么?清楚的例子会很棒! :d

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

javascript boolean bitwise-operators boolean-logic
9个回答
181
投票

因为没有人提出过为什么这些有用的主题:

使用标志时,我经常使用按位运算。例如,如果要将一系列标志传递给某个操作(例如,File.Open(),同时启用了“读取”模式和“写入”模式),则可以将它们作为单个值传递。这是通过在bitset(byte,short,int或long)中为每个可能的标志分配它自己的位来实现的。例如:

 Read: 00000001
Write: 00000010

因此,如果你想传递读和写,你将传递(READ | WRITE),然后将两者结合起来

00000011

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

if ((flag & Read) != 0) { //...

检查

00000011 &
00000001

返回

00000001

这不是0,因此该标志确实指定READ。

您可以使用XOR切换各种位。我在使用标志指定方向输入(向上,向下,向左,向右)时使用了这个。例如,如果一个精灵正在水平移动,我想让它转过来:

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

在这种情况下,我只是将当前值与(LEFT | RIGHT)进行异或,它将关闭LEFT和RIGHT。

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

x << y

是相同的

x * 2y

如果你需要快速乘以2的幂,但要注意将1位移入最高位 - 这使得数字为负数,除非它是无符号的。它在处理不同大小的数据时也很有用。例如,从四个字节读取整数:

int val = (A << 24) | (B << 16) | (C << 8) | D;

假设A是最重要的字节而D是最小的。最终会:

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

颜色通常以这种方式存储(最重要的字节被忽略或用作Alpha):

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

0xFF11111111相同。基本上,对于Red来说,你会这样做:

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)

27
投票

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

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个独立的“AND”操作,每列一个。

我提到这个是因为我还记得有这个“AHA!”多年前我了解这一点的那一刻。


27
投票

按位运算符是一次运算的运算符。

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

如果其中一个或多个输入为1,则OR为1。

仅当其中一个输入为1时,XOR才为1。

仅当输入为0时,NOT才为1。

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

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),所以:

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011

15
投票

这些是按位运算符,所有都支持JavaScript:

  • op1 & op2 - AND运算符比较两位,如果两个位都为1,则生成1的结果;否则,它返回0。
  • op1 | op2 - OR运算符比较两位,如果位是互补的,则生成1的结果;否则,它返回0。
  • op1 ^ op2 - EXCLUSIVE-OR运算符比较两位,如果其中任何一位为1则返回1,如果两位都为0或1则返回0。
  • ~op1 - COMPLEMENT运算符用于反转操作数的所有位。
  • op1 << op2 - SHIFT LEFT运算符向左移动位,丢弃最左边的位,并将最右边的位赋值为0.每次向左移动都有效地将op1乘以2。
  • op1 >> op2 - SHIFT RIGHT运算符将位向右移动,丢弃最右边的位,并将最左边的位赋值为0.每次向右移动都有效地将op1分成两半。最左边的符号位被保留。
  • op1 >>> op2 - SHIFT RIGHT - ZERO FILL运算符向右移动位,丢弃最右边的位,并将最左边的位赋值为0.每次向右移动都有效地将op1分成两半。最左边的符号位被丢弃。

4
投票

为了进一步细分,它与所讨论的值的二进制表示有很大关系。

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

希望这可以帮助。


4
投票

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

例如,在JavaScript中,bitwise operators treat their operands as a sequence of 32 bits (zeros and ones);同时,logical operators are typically used with Boolean (logical) values但可以使用非布尔类型。

以expr1 && expr2为例。

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

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

正如其他人所说,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>

2
投票

在数字计算机编程中,按位操作在其各个位的级别上对一个或多个位模式或二进制数字进行操作。它是处理器直接支持的快速,原始动作,用于操作值进行比较和计算。

操作:

  • 按位AND
  • 按位OR
  • 按位NOT
  • 按位异或
  • 等等

项目清单

    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

使用按位运算符

  • 左移和右移算子分别相当于乘法和除以x * 2y。

例如。

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
  • 如果没有qazxsw poi语句,快速找到x和y的最小值

例如。

if else
  • 十进制到二进制转换

例如。

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • XOR门加密是一种流行的技术,因为它的复杂性和程序员很少使用。 从技术访谈的角度来看,按位XOR运算符是最有用的运算符。

按位移位仅适用于+ ve数

按位逻辑也有广泛的用途


1
投票

以这种方式思考它可能会有所帮助。这是AND(&)的工作原理:

它基本上都说是这两个数字,所以如果你有两个数字5和3它们将被转换成二进制,计算机会认为

#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 ;
}

都是一个:00000001 0是假,1是真

所以5和3的AND是一个。 OR(|)运算符执行相同的操作,但只有一个数字必须是1才能输出1,而不是两者。


-5
投票

我一直听说JavaScript按位运算符的速度有多慢。我对 5: 00000101 3: 00000011 进行了一些测试,结果发现它们比几次测试中的算术选择快了40%到80%。也许他们过去很慢。在现代浏览器中,我喜欢它们。

我的代码中有一个案例会因此而更快更容易阅读。我会睁大眼睛看更多。

© www.soinside.com 2019 - 2024. All rights reserved.