博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
What are bitwise operators?
阅读量:4031 次
发布时间:2019-05-24

本文共 7588 字,大约阅读时间需要 25 分钟。

75
54

I'm someone who writes code just for fun and haven't really delved into it in either an academic or professional setting, so stuff like these bitwise operators really escapes me.

I was reading an article about JavaScript, which apparently supports bitwise operations. I keep seeing this operation mentioned in places, and I've tried reading about to figure out what exactly it is, but I just don't seem to get it at all. So what are they? Clear examples would be great! :D

Just a few more questions - what are some practical applications of bitwise operations? When might you use them?

 
 
I'm someone who mainly writes code just for fun and I've written a functional (but limited) microkernel. In x86 assembly language. For fun. :D –   
2  
For further questions, you might want to add a new SO question and reference this one. You'll probably get a better set of answers that way. –   

9 Answers

113
accepted

Since nobody has broached the subject of why these are useful:

I use bitwise operations a lot when working with flags. For example, if you want to pass a series of flags to an operation (say, File.Open, with Read mode and Write mode both enabled), you could pass them as a single value. This is accomplished by assigning each possible flag it's own bit in a bitset (byte, short, int, or long). For example:

Read: 00000001Write: 00000010

So if you want to pass read AND write, you would pass (READ | WRITE) which then combines the two into 

00000011

Which then can be decrypted on the other end like:

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

which checks

00000011 &00000001

which returns

00000001

which is not 0, so the flag does specify READ.

You can use XOR to toggle various bits. I've used this when using a flag to specify directional inputs (Up, Down, Left, Right). For example, if a sprite is moving horizontally, and I want it to turn around:

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

I simply XOR the current value with (LEFT | RIGHT) which will turn LEFT off and RIGHT on, in this case.

Bit Shifting is useful in several cases.

x << y

is the same as

x * 2y

if you need to quickly multiply by a power of two, but watch out for shifting a 1-bit into the top bit - this makes the number negative unless it's unsigned. It's also useful when dealing with different sizes of data. For example, reading an integer from four bytes:

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

Assuming that A is the most-significant byte and D the least. It would end up as:

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

Colors are often stored this way (with the most significant byte either ignored or used as Alpha):

A = 255 = 11111111R = 21 = 00010101G = 255 = 11111111B = 0 = 00000000Color = 11111111 00010101 11111111 00000000

To find the values again, just shift the bits to the right until it's at the bottom, then mask off the remaining higher-order bits:

Int Alpha = Color >> 24Int Red = Color >> 16 & 0xFFInt Green = Color >> 8 & 0xFFInt Blue = Color & 0xFF

0xFF is the same as 11111111. So essentially, for Red, you would be doing this:

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)
 
11  
+1 this is the only good answer given –   
1  
great description! Thanks! –   
18

Bitwise operators are operators that work on a bit at a time.

AND is 1 only if both of its inputs are 1.

OR is 1 if one or more of its inputs are 1.

XOR is 1 only if exactly one of its inputs are 1.

NOT is 1 only if its input are 0.

These can be best described as truth tables. Inputs possibilities are on the top and left, the resultant bit is one of the four (two in the case of NOT since it only has one input) values shown at the intersection of the two inputs.

AND|0 1      OR|0 1---+----    ---+----  0|0 0       0|0 1  1|0 1       1|1 1XOR|0 1     NOT|0 1---+----    ---+---  0|0 1        |1 0  1|1 0

One example is if you only want the lower 4 bits of an integer, you AND it with 15 (binary 1111) so:

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

It is worth noting that the single-bit truth tables listed as other answers work on only one or two input bits at a time. What happens when you use integers, such as:

int x = 5 & 6;

The answer lies in the binary expansion of each input:

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

Each pair of bits in each column is run through the "AND" function to give the corresponding output bit on the bottom line. So the answer to the above expression is 4. The CPU has done (in this example) 8 separate "AND" operations in parallel, one for each column.

I mention this because I still remember having this "AHA!" moment when I learned about this many years ago.

 
 
Wow, that makes a lot more sense now. It sounded a lot more complicated than it apparently is. Thanks. I'm not sure which to choose as the right answer as there are loads of good ones, and I can't upvote so.. thanks –   
10

These are the bitwise operators, all supported in JavaScript:

  • op1 & op2 -- The AND operator compares two bits and generates a result of 1 if both bits are 1; otherwise, it returns 0.

  • op1 | op2 -- The OR operator compares two bits and generates a result of 1 if the bits are complementary; otherwise, it returns 0.

  • op1^ op2 -- The EXCLUSIVE-OR operator compares two bits and returns 1 if either of the bits are 1 and it gives 0 if both bits are 0 or 1.

  • ~op1 -- The COMPLEMENT operator is used to invert all of the bits of the operand.

  • op1 << op2 -- The SHIFT LEFT operator moves the bits to the left, discards the far left bit, and assigns the rightmost bit a value of 0. Each move to the left effectively multiplies op1 by 2.

  • op1 >> op2 -- The SHIFT RIGHT operator moves the bits to the right, discards the far right bit, and assigns the leftmost bit a value of 0. Each move to the right effectively divides op1 in half. The left-most sign bit is preserved.

  • op1 >>> op2 -- The SHIFT RIGHT - ZERO FILL operator moves the bits to the right, discards the far right bit, and assigns the leftmost bit a value of 0. Each move to the right effectively divides op1 in half. The left-most sign bit is discarded.

 
2  
Not in all languages. –   
2

To break it down a bit more, it has a lot to do with the binary representation of the value in question. 

For example (in decimal):x = 8y = 1would come out to (in binary):x = 1000y = 0001From there, you can do computational operations such as 'and' or 'or'; in this case:x | y = 1000 0001 |------1001or...9 in decimal

Hope this helps. 

 
1

When the term "bitwise" is mentioned, it is sometimes clarifying that is is not a "logical" operator.

For example in JavaScript, ; meanwhile,  but can work with non-Boolean types.

Take expr1 && expr2 for example.

Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

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

As others have noted, 2 & 4 is a bitwise AND, so it will return 0.

You can copy the following to test.html or something and test:

 

转载地址:http://zshbi.baihongyu.com/

你可能感兴趣的文章
可以在线C++编译的工具站点
查看>>
关于无人驾驶的过去、现在以及未来,看这篇文章就够了!
查看>>
所谓的进步和提升,就是完成认知升级
查看>>
昨夜今晨最大八卦终于坐实——人类首次直接探测到了引力波
查看>>
如何优雅、机智地和新公司谈薪水?
查看>>
为什么读了很多书,却学不到什么东西?
查看>>
长文干货:如何轻松应对工作中最棘手的13种场景?
查看>>
如何确保自己的Mac数据安全呢?这里有四个“小秘诀”
查看>>
如何用好碎片化时间,让思维更有效率?
查看>>
第一性原理:戳中问题本质的人是怎么思考的?
查看>>
No.147 - LeetCode1108
查看>>
No.148 - LeetCode771
查看>>
No.174 - LeetCode1305 - 合并两个搜索树
查看>>
No.175 - LeetCode1306
查看>>
No.176 - LeetCode1309
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
mac:移动python包路径
查看>>
mysql:sql create database新建utf8mb4 数据库
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql alter table 修改列属性的字符集
查看>>