Update
parent
49f5a12c8b
commit
2a3266e7b6
@ -0,0 +1,160 @@
|
||||
# Bit Hack
|
||||
|
||||
Bit hacks or bit tricks are simple clever formulas for performing useful operations with [binary](binary.md) numbers. Some operations, such as checking if a number is power of two or reversing bits in a number, can be done very efficiently with these hacks, without using loops, [branching](branchless.md) and other undesirably slow operations, potentially increasing speed and/or decreasing size and/or memory usage of code -- this can help us [optimize](optimization.md). Many of these can be found on the [web](www.md) and there are also books such as *Hacker's Delight* which document such hacks.
|
||||
|
||||
## Specific Bit Hacks
|
||||
|
||||
{ Work in progress. I'm taking these from various sources such as the *Hacker's Delight* book or web and rewriting them a bit, always testing. Some of these are my own. ~drummyfish }
|
||||
|
||||
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.
|
||||
|
||||
**2^N**: `1 << N`
|
||||
|
||||
**[absolute value](abs.md) of x ([two's complement](twos_complement.md))**:
|
||||
|
||||
```
|
||||
int t = x >> (sizeof(x) * 8 - 1);
|
||||
x = (x + t) ^ t;
|
||||
```
|
||||
|
||||
**average x and y without overflow**: `(x & y) + ((x ^ y) >> 1)` { TODO: works with unsigned, not sure about signed. ~drummyfish }
|
||||
|
||||
**clear (to 0) Nth bit of x**: `x & ~(1 << N)`
|
||||
|
||||
**clear (to 0) rightmost 1 bit of x**: `x & (x - 1)`
|
||||
|
||||
**conditionally add (subtract etc.) x and y based on condition c (c is 0 or 1)**: `x + ((0 - c) & y)`, this avoids branches AND ALSO multiplication by c, of course you may replace + by another operators.
|
||||
|
||||
**count 0 bits of x**: Count 1 bits and subtract from data type width.
|
||||
|
||||
**count 1 bits of x (8 bit)**: We add neighboring bits in parallel, then neighboring groups of 2 bits, then neighboring groups of 4 bits.
|
||||
|
||||
```
|
||||
x = (x & 0x55) + ((x >> 1) & 0x55);
|
||||
x = (x & 0x33) + ((x >> 2) & 0x33);
|
||||
x = (x & 0x0f) + (x >> 4);
|
||||
```
|
||||
|
||||
**count 1 bits of x (32 bit)**: Analogous to 8 bit version.
|
||||
|
||||
```
|
||||
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
|
||||
x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
|
||||
x = (x & 0x0000ffff) + (x >> 16);
|
||||
```
|
||||
|
||||
**count leading 0 bits in x (8 bit)**:
|
||||
|
||||
```
|
||||
int r = (x == 0);
|
||||
if (x <= 0x0f) { r += 4; x <<= 4; }
|
||||
if (x <= 0x3f) { r += 2; x <<= 2; }
|
||||
if (x <= 0x7f) { r += 1; }
|
||||
```
|
||||
|
||||
**count leading 0 bits in x (32 bit)**: Analogous to 8 bit version.
|
||||
|
||||
```
|
||||
int r = (x == 0);
|
||||
if (x <= 0x0000ffff) { r += 16; x <<= 16; }
|
||||
if (x <= 0x00ffffff) { r += 8; x <<= 8; }
|
||||
if (x <= 0x0fffffff) { r += 4; x <<= 4; }
|
||||
if (x <= 0x3fffffff) { r += 2; x <<= 2; }
|
||||
if (x <= 0x7fffffff) { r += 1; }
|
||||
```
|
||||
|
||||
**divide x by 2^N**: `x >> N`
|
||||
|
||||
**divide x by 3 (unsigned at least 16 bit, x < 256)**: `((x + 1) * 85) >> 8`, we use kind of a [fixed point](fixed_point.md) multiplication by reciprocal (1/3), on some platforms this may be faster than using the divide instruction, but not always (also compilers often do this for you). { I checked this particular trick and it gives exact results for any x < 256, however this may generally not be the case for other constants than 3. Still even if not 100% accurate this can be used to approximate division. ~drummyfish }
|
||||
|
||||
**divide x by 5 (unsigned at least 16 bit, x < 256)**: `((x + 1) * 51) >> 8`, analogous to divide by 3.
|
||||
|
||||
**get Nth bit of x**: `(x >> N) & 0x01`
|
||||
|
||||
**is x a power of 2?**: `x && ((x & (x - 1)) == 0)`
|
||||
|
||||
**is x even?**: `(x & 0x01) == 0`
|
||||
|
||||
**is x odd?**: `(x & 0x01)`
|
||||
|
||||
**isolate rightmost 0 bit of x**: `~x & (x + 1)`
|
||||
|
||||
**isolate rightmost 1 bit of x**: `x & (~x + 1)` (in [two's complement](twos_complement.md) equivalent to `x & -x`)
|
||||
|
||||
**log base 2 of x**: Count leading 0 bits, subtract from data type width - 1.
|
||||
|
||||
**maximum of x and y**: `x ^ ((0 - (x < y)) & (x ^ y))`
|
||||
|
||||
**minimum of x and y**: `x ^ ((0 - (x > y)) & (x ^ y))`
|
||||
|
||||
**multiply x by 2^N**: `x << N`
|
||||
|
||||
**multiply by 7 (and other numbers close to 2^N)**: `(x << 3) - x`
|
||||
|
||||
**next higher or equal power of 2 from x (32 bit)**:
|
||||
|
||||
```
|
||||
x--;
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
x = x + 1 + (x == 0);
|
||||
```
|
||||
|
||||
**[parity](parity.md) of x (8 bit)**:
|
||||
|
||||
```
|
||||
x ^= x >> 1;
|
||||
x ^= x >> 2;
|
||||
x = (x ^ (x >> 4)) & 0x01;
|
||||
```
|
||||
|
||||
**reverse bits of x (8 bit)**: We switch neighboring bits, then switch neighboring groups of 2 bits, then neighboring groups of 4 bits.
|
||||
|
||||
```
|
||||
x = ((x >> 1) & 0x55) | ((x & 0x55) << 1);
|
||||
x = ((x >> 2) & 0x33) | ((x & 0x33) << 2);
|
||||
x = ((x >> 4) & 0x0f) | (x << 4);
|
||||
```
|
||||
|
||||
**reverse bits of x (32 bit)**: Analogous to the 8 bit version.
|
||||
|
||||
```
|
||||
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
|
||||
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
|
||||
x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
|
||||
x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
|
||||
x = ((x >> 16) & 0x0000ffff) | (x << 16);
|
||||
```
|
||||
|
||||
**rotate x left by N (8 bit)**: `(x << N) | (x >> (8 - N))` (watch out, in C: N < 8, if storing in wider type also do `& 0xff`)
|
||||
|
||||
**rotate x right by N (8 bit)**: analogous to left rotation, `(x >> N) | (x << (8 - N))`
|
||||
|
||||
**set (to 1) Nth bit of x**: `x | (1 << N)`
|
||||
|
||||
**set (to 1) the rightmost 0 bit of x**: `x | (x + 1)`
|
||||
|
||||
**set or clear Nth bit of x to b**: `(x & ~(1 << N)) | (b << N)`
|
||||
|
||||
**sign of x (returns 1, 0 or -1)**: `(x > 0) - (x < 0)`
|
||||
|
||||
**swap x and y (without tmp var.)**: `x ^= y; y ^= x; x ^= y;` or `x -= y; y += x; x = y - x;`
|
||||
|
||||
**toggle Nth bit of x**: `x ^ (1 << N)`
|
||||
|
||||
**toggle x between A and B**: `(x ^ A) ^ B`
|
||||
|
||||
**x and y have different signs?**: `(x > 0) == (y > 0)`, `(x <= 0) == (y <= 0)` etc. (differs on 0:0 behavior)
|
||||
|
||||
TODO: the ugly hacks that use conversion to/from float?
|
||||
|
||||
## See Also
|
||||
|
||||
- [De Morgan's laws](de_morgans_laws.md)
|
||||
- [fast inverse square root](fast_inverse_sqrt.md)
|
||||
- [optimization](optimization.md)
|
@ -1,5 +1,9 @@
|
||||
# Proprietary Software
|
||||
|
||||
Proprietary software is any software that is not [free (as in freedom)](free_software.md)/[open source](open_source.md) software. Such software denies users and creators their basic freedoms (freedom of unlimited use, studying, modifying and sharing) and is therefore considered [evil](evil.md), in fact it is mostly [capitalist software](capitalist_software.md) designed to abuse its user in some way. Examples of proprietary software are [MS Windows](windows.md), [MacOS](macos.md), [Adobe Photoshop](photoshop.md) and almost every [game](game.md).
|
||||
Proprietary software is any software that is not [free (as in freedom)](free_software.md)/[open source](open_source.md) software. Such software denies users and creators their basic freedoms (freedom of unlimited use, studying, modifying and sharing) and is therefore [evil](evil.md); proprietary software is mostly [capitalist software](capitalist_software.md) designed to abuse its user in some way. Proprietary code is often secret, not publicly accessible, but there are many programs whose source code is [available](source_available.md) but which is still proprietary because no one except the "owner" has any legal rights to fixing it, improving it or redistributing it.
|
||||
|
||||
Proprietary software licenses are usually called [EULAs](eula.md).
|
||||
Examples of proprietary software are [MS Windows](windows.md), [MacOS](macos.md), [Adobe Photoshop](photoshop.md) and almost every [game](game.md). Proprietary software is not only extremely [harmful](harmful.md) to culture, progress and society in general, it is downright dangerous and in some cases life-threatening; see for example cases of medical implants such as pacemakers running secret proprietary code whose creator and maintainer goes bankrupt and can no longer continue to maintain such devices already planted into bodies of people -- such cases have already appeared, see e.g. *Autonomic Technologies* nervous system implants.
|
||||
|
||||
Proprietary software licenses are usually called [EULAs](eula.md).
|
||||
|
||||
By extension besides proprietary software there also exist other proprietary works, for example proprietary [art](art.md) or databases -- these are all works that are not [free cultural works](free_culture.md). Even though for example a proprietary movie probably isn't IMMEDIATELY as dangerous as proprietary software, it may be just as dangerous to society in the long run.
|
Loading…
Reference in New Issue