/en/_posts/2011-11-23-Working-with-bits.markdown

https://github.com/nimdahk/ahkbook · Markdown · 114 lines · 83 code · 31 blank · 0 comment · 0 complexity · ac8d8a4f395244c320b88198e7c7563b MD5 · raw file

  1. ---
  2. title: Working with bits
  3. layout: post
  4. permalink: /en/Working-with-bits.html
  5. ---
  6. # Bitwise Operations #
  7. ## Understanding Binary
  8. ### Base 10 ###
  9. Binary, or Base 2, is simply another way to write numbers. In everyday life, we use Base 10. We have the Ones place, the Tens place, the Hundreds place, and so on. More technically, each digit is multiplied by ``10 ** n``, where ``n`` represents the distance from the right, starting from 0. (In AutoHotkey, ``**`` represents exponents or "powers"). Thus, the number 647 in Base 10 is equivalent to ``(6 * 100) + (4 * 10) + (7 * 1)``, or ``(6 * 10**2) + (4 * 10**1) + (7 * 10**0)`` in binary. (Yes, ``10**0`` is 1, and this is no place to discuss why.)
  10. ### Base 2 ###
  11. Base 2 (Binary) works exactly the same way. Each digit is multiplied by ``2 ** n``, where *n* is the distance from the right, starting at 0. Thus, the number 1101001 in binary is equivalent to ``(1 * 64) + (1 * 32) + (0 * 16) + (1 * 8) + (0 * 4) + (0 * 2) + (1 * 1)``. In base 10, that is 105.
  12. ### Bits ###
  13. Integers are stored in a computer as *bits*.
  14. A *bit* is a binary digit. It is the simplest way to represent data: on or off,
  15. 1 or 0, true or false. All integers can be represented as Binary in bits, if there are a sufficient number of them.
  16. Put several bits together and you have a number in Base 2.
  17. You might see terms such as "32-bit integer" or "64-bit integers" when dealing
  18. with binary. These refer to the number of bits (digits) used to store the number.
  19. Naturally, the more bits used, the higher the integer that can be stored.
  20. ## Basic Operations ##
  21. So what is 1+1 in Binary? It's certainly not 2; binary doesn't have a 2! It's *10*, which means ``(1 * 2**1) + (0 * 2**0)``. All of the basic arithmetic operations — addition, subtraction, multiplication, and division — work in binary just as well as they do in Base 10. Because of this, there's no real reason to use them in Binary as opposed to base 10. However, there are some other operations which always pertain to Binary: the bitwise AND, the bitwise OR, the bitwise XOR, the bitwise NOT, and the bit-shifts left and right.
  22. ### The Bitwise AND ###
  23. The bitwise AND (represented by a single ampersand '&' in AutoHotkey) takes two digits at a time. If they are both 1, then the result is 1. Otherwise, the result is false. Here's an example:
  24. 1100
  25. &1010
  26. _____
  27. 1000
  28. Notice how the only '1' in the result occurred when both operands had a 1 in that place. 1 & 1 = 1; 1 & 0 = 0; 0 & 1 = 0; 0 & 0 = 0.
  29. ### The Bitwise OR ###
  30. The bitwise OR (a single pipe '|' in AutoHotkey) has a different effect. It takes two operands, and if *at least one* of them is true (a 1) then the result is 1. Example:
  31. 1100
  32. |1010
  33. _____
  34. 1110
  35. Notice how the only '0' in the result occurred when both operands (digits) were 0.
  36. ### The Bitwise NOT ###
  37. The bitwise NOT (~ in AutoHotkey) takes only *one* operand. It then "flips" every bit (digit) — if it is 0, the result is 1, if it is 1, the result is 0. Example 1:
  38. ~1010
  39. _____
  40. 0101
  41. Example 2:
  42. ~0001
  43. _____
  44. 1110
  45. ### The Bitwise XOR ###
  46. The bitwise XOR, short for eXclusive-OR (*Note:* the bitwise XOR is ^ in AutoHotkey; ** is used to represent exponentiation) takes two operands. If they are not the same, the result is 1, otherwise it is 0. Another way of saying this is "one or the other is true, but not both" (which is where the term exclusive OR comes from.) Example:
  47. 1010
  48. ^1100
  49. _____
  50. 0110
  51. ### The Bit shift left and the bit shift right ###
  52. The bit shift left (<<) and the bit shift right (>>) take one operand. Then, they literally slide the bits (digits) left or right. Example:
  53. 00001010 << 3
  54. _____________
  55. 01010000
  56. Another:
  57. 0011100 >> 2
  58. ____________
  59. 0000111
  60. Note that if you shift a bit off of the side, it will "fall off": it is lost. Example:
  61. 0101 >> 1
  62. _________
  63. 0010
  64. These operators are very similar to multiplying by or dividing by powers of 2. (Which should make sense, since binary is Base 2). Therefore, ``3 << 5`` is the same as ``3 * 2**5`` (remember, in AutoHotkey, ** represents exponentiation), which equals 96. Remember that digits slide off, so ``3 >> 1`` is not 1.5 (3/2) but rather *1*. See the example:
  65. 0011 (3 in binary)
  66. >> 1 (slide it to the right by 1)
  67. ____
  68. 0001 (1 in binary)
  69. ## Bitwise Assignments ##
  70. Bitwise assignments are slightly odd-looking creatures such as ``>>=``, ``^=``, and ``|=``. These take a variable to the left and an argument to the right, plug them into an operation (specified by the type of operator before the equals-sign), evaluate the result, and store it back into the variable. For example,
  71. {% highlight ahk lineos %}
  72. MyVar := 5 ; 101 in binary
  73. MyVar |= 2 ; 101 | 010 = 111 = 7
  74. MsgBox % MyVar ; 7
  75. MyVar := 5 ; 101 in binary
  76. MyVar <<= 2 ; 101<<2 = 10100 = 20
  77. MsgBox % MyVar ; 20
  78. {% endhighlight %}
  79. ## Conclusion: Real applications ##
  80. Now that you know the basics of Binary and operations you can do on it, what is it useful for? Probably not a lot in everyday scripting, but it becomes more useful with the WinAPI and structures that need to be passed to it. It does occasionally pop up in unexpected places like the [MsgBox](http://l.autohotkey.net/docs/commands/MsgBox.htm) command. Take a look at the options. How does the command know if you want a particular option (if you've added one option to another)? It uses bitwise operations. For example, if you want a question mark and the buttons Yes, No, and Cancel, you would add 3+32 to get 35. The MsgBox command can then use bitwise operations (pseudo-code):
  81. If (VarContaining35 & 32)
  82. ; add the '?' icon
  83. This works because each option which can only have 2 states &#8212; on or off &#8212; (all except the 'button' ones) is a multiple of 2, and therefore has only a single 1 in its binary representation. Therefore, OR'ing them all together is the same as adding them, and you can retrieve the value of a single bit (option) by using the binary AND operator.