markdown js-bitwise-hacks.md
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown js-bitwise-hacks.md相关的知识,希望对你有一定的参考价值。
## JavaScript Bitwise Hacks
It assumes the highest positive signed 32-bit float value for numbers.
In other words, ```2147483647``` (or ```0x7FFFFFFF``` or ```2^31-1```).
## Table of Contents
1. [Toggle switch](#toggle-switch)
1. [Variable swap](#variable-swap)
1. [Math.pow](#mathpow)
1. [Determine if an integer is a power of 2](#determining-if-an-integer-is-a-power-of-2)
1. [Round up to the next highest power of 2](#round-up-to-the-next-highest-power-of-2)
1. [Determine if two integers have opposite signs](#determine-if-two-integers-have-opposite-signs)
1. [Check if the integer is even or odd](#check-if-the-integer-is-odd-or-even)
1. [Integer division and multiplication](#integer-multiplication-and-division)
1. [Modulus division without a division operator](#modulus-division-without-a-division-operator)
1. [Math.floor](#mathfloor)
1. [Math.max](#mathmax)
1. [Check if value cannot be parsed to a number](#check-if-value-cannot-be-parsed-to-a-number)
1. [Convert colors from RGB to Hex format](#convert-colors-from-rgb-to-hex-format)
1. [Get the difference between two hex values](#get-the-difference-between-two-hex-values)
1. [Create array of bits of a number](#create-array-of-bits-of-a-number)
1. [Counting bits in a 32-bit integer](#counting-bits-in-a-32-bit-integer)
1. [Merge bits from two values according to a mask](#merge-bits-from-two-values-according-to-a-mask)
1. [Test if the n-th bit is set](#test-if-the-n-th-bit-is-set)
1. [Set the n-th bit](#set-the-n-th-bit)
1. [Unset the n-th bit](#unset-the-n-th-bit)
1. [Toggle the n-th bit](#toggle-the-n-th-bit)
1. [Turn off the rightmost 1-bit](#turn-off-the-rightmost-1-bit)
1. [Isolate the rightmost 1-bit](#isolate-the-rightmost-1-bit)
1. [Right propagate the rightmost 1-bit](#right-propagate-the-rightmost-1-bit)
1. [Isolate the rightmost 0-bit](#isolate-the-rightmost-0-bit)
1. [Turn on the rightmost 0-bit](#turn-on-the-rightmost-0-bit)
1. [Checking that all bits are the same](#checking-that-all-bits-are-the-same)
1. [Identify trailing zeroes](#identify-trailing-zeroes)
1. [Identify rightmost set and trailing unset](#identify-rightmost-set-and-trailing-unset)
### Toggle switch
```js
var v = 1;
v ^= 1; // => 0
v ^= 1; // => 1
v ^= 1; // => 0
v ^= 1; // => 1
```
**[Back to top](#table-of-contents)**
### Variable swap
```js
var x = 1;
var y = -2;
x ^= y;
y ^= x;
x ^= y;
x; // => -2
y; // => 1
```
**[Back to top](#table-of-contents)**
### ```Math.pow```
Bitwise left shift operator can be a replacement for Math.pow()
when dealing with bases of 2:
```js
Math.pow(2, 12) === 1 << 12
// => true
```
**[Back to top](#table-of-contents)**
### Determining if an integer is a power of 2
```js
v && !(v & (v - 1));
```
**[Back to top](#table-of-contents)**
### Round up to the next highest power of 2
```js
var v = 5; // unsigned integer;
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
++v;
// => 8
```
**[Back to top](#table-of-contents)**
### Determine if two integers have opposite signs
**_NOTE_**: fails for 0 and -0
```js
var x = 1;
var y = 1;
(x ^ y) < 0;
// => false
```
**[Back to top](#table-of-contents)**
### Check if the integer is odd or even
```js
if (v & 1) {
// v is odd
}
else {
// v is even
}
```
**Why?** The righmost or zeroth bit of odd number is always set.
**[Back to top](#table-of-contents)**
### Integer multiplication and division
```js
20.5 << 1; // <~> 20 * 2
// => 40
20.5 >> 1; // <~> 20 / 2
// => 10
```
**[Back to top](#table-of-contents)**
### Modulus division without a division operator
#### Modulus division by ```1 << s```
```js
var n = 20; // unsigned integer; numerator
var s = 3; // unsigned integer; power of 2
var d = 1 << s; // unsigned integer; d will be one of: 1, 2, 4, 8, 16, 32, ...
var m = n & (d - 1); // unsigned integer; m will be n % d
m === 20 % 8;
// => true
```
#### Modulus division by ```(1 << s) - 1```
```js
var n = 20; // unsigned integer; numerator
var s = 3; // unsigned integer > 0; power of 2
var d = (1 << s) - 1; // unsigned integer; so d is either 1, 3, 7, 15, 31, ...).
var m; // unsigned integer; n % d goes here.
for (m = n; n > d; n = m) {
for (m = 0; n; n >>= s) {
m += n & d;
};
};
// Now m is a value from 0 to d,
// but since with modulus division we want m to be 0 when it is d.
m = (m == d) ? 0 : m;
m === 20 % 7;
// => true
```
**[Back to top](#table-of-contents)**
### ```Math.floor```
```js
```
**[Back to top](#table-of-contents)**
### ```Math.max```
```js
var x = 2410;
var y = 19;
Math.max(x, y) === (x ^ ((x ^ y) & -(x < y)));
// => true
Math.min(x, y) === (y ^ ((x ^ y) & -(x < y)));
// => true
```
**[Back to top](#table-of-contents)**
### Check if value cannot be parsed to a number
**_NOTE_**: the result will always be zero
```js
~~NaN
// => 0
~~'hello'
// => 0
~~{}
// => 0
~~[]
// => 0
~~function doSmth(){}
// => 0
~~false
// => 0
~~true
// => 1
NaN >>> 0
// => 0
'hello' >>> 0
// => 0
({} >>> 0)
// => 0
[] >>> 0
// => 0
(function doSmth(){}) >>> 0
// => 0
false >>> 0
// => 0
true >>> 0
// => 1
```
**[Back to top](#table-of-contents)**
### Convert colors from RGB to Hex format
```js
var color = { r: 186, g: 218, b: 85 };
var rgb2hex = function(r, g, b) {
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
rgb2hex(color.r, color.g, color.b);
// => '#bada55'
```
**[Back to top](#table-of-contents)**
### Get the difference between two hex values
```js
var a = 0xF0; // 240
var b = 0xFF; // 255
~a & b;
// => 15
```
**[Back to top](#table-of-contents)**
### Create array of bits of a number
```js
var num = 5;
var index = 0;
var mask = 128;
var bits = [];
while (mask > 0) {
mask >>= 1;
index++;
bits.push((mask & num ? 1 : 0));
};
bits;
// => [0, 0, 0, 0, 0, 1, 0, 1]
parseInt(bits.join(''), 2);
// => 5
```
**[Back to top](#table-of-contents)**
### Counting bits in a 32-bit integer
#### The naive way
```js
var v = 5;
var count; // accumulates the total bits set in v
for (count = 0; v; v >>= 1) {
count += v & 1;
};
// The naive approach requires one iteration per bit, until no more bits are set.
// So on a 32-bit word with only the high set, it will go through 32 iterations.
```
#### Brian Kernighan's way
```js
var v = 5;
var count;
for (count = 0; v; count++) {
v &= v - 1; // clear the least significant bit set
};
// Brian Kernighan's method goes through as many iterations as there are set bits.
// So if we have a 32-bit word with only the high bit set, then it will only go once through the loop.
```
#### The best approach
```js
var v = 5;
var count;
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
count = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
```
**[Back to top](#table-of-contents)**
### Merge bits from two values according to a mask
```js
var x; // unsigned integer to merge in non-masked bits
var y; // unsigned integer to merge in masked bits
var mask; // unsigned integer; 1 where bits from y should be selected; 0 where from x.
var r; // unsigned integer; result of (x & ~mask) | (y & mask) goes here
r = x ^ ((x ^ y) & mask);
// This shaves one operation from the obvious way of combining two sets of bits according to a bit mask.
```
**[Back to top](#table-of-contents)**
### Test if the n-th bit is set
```js
if (v & (1 << n)) {
// n-th bit is set
}
else {
// n-th bit is not set
}
```
**[Back to top](#table-of-contents)**
### Set the n-th bit
```js
v | (1 << n);
```
**[Back to top](#table-of-contents)**
### Unset the n-th bit
```js
v & ~(1 << n);
// b = a | ~(1 << n);
// Shift 1 n times left, complement it or it with a and then put it into a new variable b.
```
**[Back to top](#table-of-contents)**
### Toggle the n-th bit
```js
v ^ (1 << n);
```
**[Back to top](#table-of-contents)**
### Right propagate the rightmost 1-bit:
```js
v | (v - 1);
```
**[Back to top](#table-of-contents)**
### Isolate the rightmost 0-bit:
```js
~v & (v + 1);
```
**[Back to top](#table-of-contents)**
### Turn on the rightmost 0-bit
```js
v | (v + 1);
```
**[Back to top](#table-of-contents)**
### Checking that all bits are the same
```js
(v & (v + 0x01)) == 0x00;
//////////////////////////
(1 & (1 + 0x01)) == 0x00;
// => true
(0 & (0 + 0x01)) == 0x00;
// => true
(2 & (2 + 0x01)) == 0x00;
// => false
(15 & (15 + 0x01)) == 0x00;
// => true
```
**[Back to top](#table-of-contents)**
### Identify trailing zeroes
```js
!!(~v & (v - 0x01));
//////////////////////////
!!(~15 & (15 - 0x01));
// => false
!!(~13 & (13 - 0x01));
// => false
!!(~0 & (0 - 0x01));
// => true
!!(~1 & (1 - 0x01));
// => false
!!(~2 & (2 - 0x01));
// => true
```
**[Back to top](#table-of-contents)**
### Turn off the rightmost 1-bit
```js
v & (v - 1);
```
**Why?** The rightmost bit of odd number is always set.
**[Back to top](#table-of-contents)**
### Isolate the rightmost 1-bit
```js
v & (-v);
```
**[Back to top](#table-of-contents)**
### Identify rightmost set and trailing unset
```js
!!(v ^ (v - 0x01));
```
**[Back to top](#table-of-contents)**
以上是关于markdown js-bitwise-hacks.md的主要内容,如果未能解决你的问题,请参考以下文章