Update
This commit is contained in:
parent
fecc1303fa
commit
ca1cf8cb6d
11 changed files with 55 additions and 36 deletions
11
bit_hack.md
11
bit_hack.md
|
@ -6,11 +6,12 @@ Bit [hacks](hacking.md) (also bit tricks, bit [magic](magic.md), bit twiddling e
|
|||
|
||||
Basic bit manipulation techniques are common and part of general knowledge so they won't be listed under hacks, but for sake of completeness and beginners reading this we should mention them here. Let's see the basic bit manipulation operators in [C](c.md):
|
||||
|
||||
- `|` (bitwise [OR](or.md)): Performs the logical OR on all corresponding bits of two operands, e.g. `0b0110 | 0b1100` gives 1110 (14 in decimal). This is used to set bits and combine flags (options) into a single numeric value that can easily be passed to function etc. For example to set the lowest bit of a number to 1 just do `myNumber | 1`. Now consider e.g. `#define OPTION_A 0b0001`, `#define OPTION_B 0b0010` and `#define OPTION_C 0b0100`, now we can make a single number that represents a set of selected options e.g. as `OPTION_C | OPTION_B` (the value will be `0101` and says that options B and C have been selected).
|
||||
- `&` (bitwise [AND](and.md)): Performs the logical AND on all corresponding bits of two operands, e.g. `0b0110 & 0b1100` gives 0100 (4 in decimal). This may be used to mask out specific bits, to check if specific bits are set (useful to check the set flags as mentioned above) or to clear (set to zero) specific bits. Consider the flag example from above, if we want to check if value *x* has e.g. the option B set, we simply do `x & OPTION_B` which results in non-zero value if the option is set. Another example may be `myNumber & 0b00001111` (in practice you'll see hexadecimal values, i.e. `myNumber & 0x0F`) which masks out the lowest 4 bits of *myNumber* (which is equivalent to the operation [modulo](mod.md) 16).
|
||||
- `~` (bitwise [NOT](not.md)): Flips every bit of the number -- pretty straightforward. This is used e.g. for clearing bits as `x & ~(1 << 3)` (clear 3rd bit of *x*).
|
||||
- `^` (bitwise [XOR](xor.md)): Performs the logical XOR on all corresponding bits of two operands, e.g. `0b0110 ^ 0b1100` gives 1010 (10 in decimal). This is used to e.g. flip specific bits.
|
||||
- `|` (bitwise [OR](or.md)): Performs the logical OR on all corresponding bits of two operands, e.g. `0b0110 | 0b1100` gives `0b1110` (14 in decimal). This is used to set bits and combine flags (options) into a single numeric value that can easily be passed to function etc. For example to set the lowest bit of a number to 1 just do `myNumber | 1`. Now consider e.g. `#define OPTION_A 0b0001`, `#define OPTION_B 0b0010` and `#define OPTION_C 0b0100`, now we can make a single number that represents a set of selected options e.g. as `OPTION_C | OPTION_B` (the value will be `0101` and says that options B and C have been selected).
|
||||
- `&` (bitwise [AND](and.md)): Performs the logical AND on all corresponding bits of two operands, e.g. `0b0110 & 0b1100` gives `0b0100` (4 in decimal). This may be used to mask out specific bits, to check if specific bits are set (useful to check the set flags as mentioned above) or to clear (set to zero) specific bits. Consider the flag example from above, if we want to check if value *x* has e.g. the option B set, we simply do `x & OPTION_B` which results in non-zero value if the option is set. Another example may be `myNumber & 0b00001111` (in practice you'll see hexadecimal values, i.e. `myNumber & 0x0F`) which masks out the lowest 4 bits of *myNumber* (which is equivalent to the operation [modulo](mod.md) 16).
|
||||
- `~` (bitwise [NOT](not.md)): Flips every bit of the number -- pretty straightforward. This is used e.g. for clearing bits as `x & ~(1 << 3)` (clear 4th bit of *x*).
|
||||
- `^` (bitwise [XOR](xor.md)): Performs the logical XOR on all corresponding bits of two operands, e.g. `0b0110 ^ 0b1100` gives `0b1010` (10 in decimal). This is used to e.g. flip specific bits.
|
||||
- `<<` and `>>` (binary shift left/right): Performs bitwise shift left or right (WATCH OUT: shifting by data type width or more is undefined behavior in C). This is typically used to perform fast multiplication (left) and division (right) by powers of two (2, 4, 8, 16, ...), just as we can quickly multiply/divide by 10 in decimal by shifting the decimal point. E.g. `5 << 3` is the same as 5 * 2^3 = 5 * 8 = 40.
|
||||
- We also sometimes use the logical (i.e. NOT bitwise) operators `&&` (AND), `||` (OR) and `!` (NOT); the difference against bitwise operators is that firstly they work with the whole value (i.e. not individual bits), considering 0 to be *false* and anything else to be *true*, and secondly they may employ a bit more complexity, e.g. [short circuit](short_circuit.md) evaluation.
|
||||
|
||||
## Specific Bit Hacks
|
||||
|
||||
|
@ -18,7 +19,7 @@ Basic bit manipulation techniques are common and part of general knowledge so th
|
|||
|
||||
TODO: stuff from this gophersite: gopher://bitreich.org/0/thaumaturgy/bithacks
|
||||
|
||||
Unless noted otherwise we suppose [C](c.md) syntax and semantics and integer [data types](data_type.md). Keep in mind all potential dangers, for example it may sometimes be better to write an idiomatic code and let compiler do the optimization that's best for given platform, also of course readability will worsen etc. Nevertheless as a hacker you should know about these tricks, it's useful for low level code etc.
|
||||
Unless noted otherwise we suppose [C](c.md) syntax and semantics and integer [data types](data_type.md), but of course we mainly want to express formulas and patterns you can use anywhere, not just in C. Keep in mind all potential dangers, for example it may sometimes be better to write an idiomatic code and let compiler do the optimization that's best for given platform, also of course readability will worsen etc. Nevertheless as a hacker you should know about these tricks, it's useful for low level code etc.
|
||||
|
||||
**2^N**: `1 << N`
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue