我已阅读'what are bitwise operators?',因此我知道 bitwise operators,但我仍然不清楚如何使用它们。任何人都可以提供任何关于位运算符在JavaScript中有用的实际示例吗?
感谢。
只需深入研究 jQuery source 我发现了几个使用按位运算符的地方,例如:(只有&运算符)
// Line 2756:
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
// Line 2101
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
答案 0 :(得分:64)
示例:
解析十六进制值以获取RGB颜色值。
var hex = 'ffaadd';
var rgb = parseInt(hex, 16); // rgb is 16755421
var red = (rgb >> 16) & 0xFF; // returns 255
var green = (rgb >> 8) & 0xFF; // 170
var blue = rgb & 0xFF; // 221
答案 1 :(得分:39)
我严重在生产脚本中使用按位运算符进行数值转换,因为有时它们比Math
或parseInt
等价物快得多。
我必须支付的价格是代码可读性。因此,我通常在开发中使用Math
,在生产中使用按位。
You can find some performance tricks on jsperf.com
正如您所看到的,浏览器多年来一直没有优化Math.ceil
和parseInt
,所以我预测bitwise会更快更短的方式来做事in furure as well。
红利:| 0
的备忘单:一种简单快捷的方式将任何内容转换为整数:
( 3|0 ) === 3; // it does not change integers
( 3.3|0 ) === 3; // it casts off the fractional part in fractionalal numbers
( 3.8|0 ) === 3; // it does not round, but exactly casts off the fractional part
( -3.3|0 ) === -3; // including negative fractional numbers
( -3.8|0 ) === -3; // which have Math.floor(-3.3) == Math.floor(-3.8) == -4
( "3"|0 ) === 3; // strings with numbers are typecast to integers
( "3.8"|0 ) === 3; // during this the fractional part is cast off too
( "-3.8"|0 ) === -3; // including negative fractional numbers
( NaN|0 ) === 0; // NaN is typecast to 0
( Infinity|0 ) === 0; // the typecast to 0 occurs with the Infinity
( -Infinity|0 ) === 0; // and with -Infinity
( null|0 ) === 0; // and with null,
( (void 0)|0 ) === 0; // and with undefined
( []|0 ) === 0; // and with an empty array
( [3]|0 ) === 3; // but an array with one number is typecast to number
( [-3.8]|0 ) === -3; // including the cast off of the fractional part
( [" -3.8 "]|0 ) === -3; // including the typecast of strings to numbers
( [-3.8, 22]|0 ) === 0 // but an Array with several numbers is typecast to 0
( {}|0 ) === 0; // an empty object is typecast to 0
( {'2':'3'}|0 ) === 0; // or a not empty object
( (function(){})|0 ) === 0; // an empty function is typecast to 0 too
( (function(){ return 3;})|0 ) === 0;
给我一些魔力:
3 | '0px' === 3;
答案 2 :(得分:24)
在JavaScript中,您可以使用双位否定(~~n
)代替Math.floor(n)
(如果n
是正数)或parseInt(n, 10)
(即使n
是否定的。 n|n
和n&n
始终会产生与~~n
相同的结果。
var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3
// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4
单个按位否定(~
)计算-(parseInt(n, 10) + 1)
,因此两个按位否定将返回-(-(parseInt(n, 10) + 1) + 1)
。
应该注意的是,在这三种选择中, n|n
appears to be the fastest 。
更新:更准确的基准: http://jsperf.com/rounding-numbers-down
答案 3 :(得分:18)
现实生活 example:
^
按位XOR为I/O
转换器 value ^= 1
和value
的每次通话都会改变0, 1, 0, 1 ...
的使用方式
function toggle(evt) {
evt.target.IO ^= 1; // Bitwise XOR as 1/0 toggler
evt.target.textContent = evt.target.IO ? "ON" : "OFF"; // Unleash your ideas
}
document.querySelectorAll("button").forEach( el =>
el.addEventListener("click", toggle)
);
<button>OFF</button>
<button>OFF</button>
<button>OFF</button>
答案 4 :(得分:16)
鉴于Javascript正在取得的进步(特别是对于允许使用js进行服务器端编程的nodejs),JS中的代码越来越复杂。以下是我使用按位运算符的几个实例:
IP地址操作:
//computes the broadcast address based on the mask and a host address
broadcast = (ip & mask) | (mask ^ 0xFFFFFFFF)
//converts a number to an ip adress
sprintf(ip, "%i.%i.%i.%i", ((ip_int >> 24) & 0x000000FF),
((ip_int >> 16) & 0x000000FF),
((ip_int >> 8) & 0x000000FF),
( ip_int & 0x000000FF));
注意:这是C代码,但JS几乎相同
查看此
上的wikipedia entry答案 5 :(得分:12)
判断一个数字是否为奇数:
function isOdd(number) {
return !!(number & 1);
}
isOdd(1); // true, 1 is odd
isOdd(2); // false, 2 is not odd
isOdd(357); // true, 357 is odd
比模数更快 - 在性能真正计数的地方使用!
答案 6 :(得分:11)
如何使用按位而不是双按位的其他几个例子:
现场操作
~~2.5 // 2
~~2.1 // 2
~~(-2.5) // -2
检查indexOf是否返回-1
var foo = 'abc';
!~foo.indexOf('bar'); // true
答案 7 :(得分:10)
您可以使用它们来翻转布尔值:
var foo = 1;
var bar = 0;
alert(foo ^= 1);
alert(bar ^= 1);
虽然这有点傻但在大多数情况下,按位运算符在Javascript中没有很多应用程序。
答案 8 :(得分:6)
var arr = ['abc', 'xyz']
懊恼写下
if (arr.indexOf('abc') > -1) {
// 'abc' is in arr
}
if (arr.indexOf('def') === -1) {
// 'def' is not in arr
}
检查数组中是否有东西?
您可以像这样使用按位运算符~
:
if (~arr.indexOf('abc')) {
// 'abc' is in arr
}
if (! ~arr.indexOf('def')) {
// 'def' is not in arr
}
答案 9 :(得分:4)
<强> Bitmasks 强>
广泛使用,例如,在JS事件中。
答案 10 :(得分:3)
我曾用permissions widget一次。 unix中的文件权限是一个位掩码,因此要解析它,您需要使用位操作。
答案 11 :(得分:2)
我正在使用它们将三个数字展平为1,作为在Uint16Array中存储多维数组的方法。这是我正在开发的体素游戏的片段:
function Chunk() {
this._blocks = new Uint16Array(32768);
this._networkUpdates = [];
}
Chunk.prototype.getBlock = function(x, y, z) {
return this._blocks[y + (x << 5) + (z << 10)];
};
Chunk.prototype.setBlock = function(x, y, z, value) {
this._blocks[y + (x << 5) + (z << 10)] = value;
this._networkUpdates.push(value + (y << 15) + (x << 20) + (z << 25));
};
Chunk.prototype.getUpdates = function() {
return this._networkUpdates;
};
Chunk.prototype.processUpdate = function(update) {
// this._blocks[Math.floor(update / 65536)] = update % 65536;
this._blocks[update >> 16] = update & 65535;
};
var chunk = new Chunk();
chunk.setBlock(10, 5, 4);
alert(chunk.getBlock(10, 5, 4));
alert(chunk.getUpdates()[0]);
答案 12 :(得分:2)
此答案包含Mark's answer的解释。
通过阅读这些解释并运行代码段,可以获得一个想法。
var hex = 'ffaadd';
var rgb = parseInt(hex, 16); // rgb value is 16755421 in decimal = 111111111010101011011101 in binary = total 24 bits
var red = (rgb >> 16) & 0xFF; // returns 255
var green = (rgb >> 8) & 0xFF; // returns 170
var blue = rgb & 0xFF; // returns 221
// HOW IS IT
// There are two bitwise operation as named SHIFTING and AND operations.
// SHIFTING is an operation the bits are shifted toward given direction by adding 0 (zero) bit for vacated bit fields.
// AND is an operation which is the same with multiplying in Math. For instance, if 9th bit of the given first bit-set is 0
// and 9th bit of the given second bit-set is 1, the new value will be 0 because of 0 x 1 = 0 in math.
// 0xFF (000000000000000011111111 in binary) - used for to evaluate only last 8 bits of a given another bit-set by performing bitwise AND (&) operation.
// The count of bits is 24 and the first 16 bits of 0xFF value consist of zero (0) value. Rest of bit-set consists of one (1) value.
console.log("0xFF \t\t\t\t: ", 0xFF)
// 111111111010101011011101 -> bits of rgb variable
// 000000000000000011111111 -> 255 after (rgb >> 16) shifting operation
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000011111111 -> result bits after performing bitwise & operation
console.log("Red - (rgb >> 16) & 0xFF \t: ", (rgb >> 16) & 0xFF) // used for to evaluate the first 8 bits
// 111111111010101011011101 -> bits of rgb variable
// 000000001111111110101010 -> 65450 -> 'ffaa'
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000010101010 -> result bits after performing bitwise & operation
// calculation -> 000000001111111110101010 & 000000000000000011111111 = 000000000000000010101010 = 170 in decimal = 'aa' in hex-decimal
console.log("Green - (rgb >> 8) & 0xFF \t: ", (rgb >> 8) & 0xFF) // used for to evaluate the middle 8 bits
// 111111111010101011011101 -> 'ffaadd'
// 000000000000000011111111 -> 255 complement (changes the first 16 bits and does nothing for the last 8 bits)
// 000000000000000011011101 -> result bits after performing bitwise & operation
// calculation -> 111111111010101011011101 & 000000000000000011111111 = 221 in decimal = 'dd' in hex-decimal
console.log("Blue - rgb & 0xFF \t\t: ", rgb & 0xFF) // // used for to evaluate the last 8 bits.
console.log("It means that `FFAADD` hex-decimal value specifies the same color with rgb(255, 170, 221)")
/* console.log(red)
console.log(green)
console.log(blue) */
答案 13 :(得分:0)
当您使用十六进制值和位时,它们似乎非常有用。由于4位可以表示0到F.
1111 = F. 1111 1111 = FF。
答案 14 :(得分:0)
使用Node.js的示例
假设您有一个包含这些内容的文件(称为multiply.js),您可以运行
`node multiply <number> <number>`
并获得与在相同的两个数字上使用乘法运算符一致的输出。 Mulitply
函数中的位移是一个示例,说明如何将位掩码表示一个数字,并使用它来翻转另一个数字中的位以进行快速操作。
var a, b, input = process.argv.slice(2);
var printUsage = function() {
console.log('USAGE:');
console.log(' node multiply <number> <number>');
}
if(input[0] === '--help') {+
printUsage();
process.exit(0);
}
if(input.length !== 2) {
printUsage();
process.exit(9);
}
if(isNaN(+input[0]) || isNaN(+input[1])) {
printUsage();
process.exit(9);
}
// Okay, safe to proceed
a = parseInt(input[0]),
b = parseInt(input[1]);
var Multiply = function(a,b) {
var x = a, y = b, z = 0;
while( x > 0 ) {
if(x % 2 === 1) {
z = z + y;
}
y = y << 1;
x = x >> 1;
}
return z;
}
var result = Multiply(a,b);
console.log(result);
答案 15 :(得分:-1)
我刚发现这个问题,试图确认Javascript中的按位AND
运算符是否也是&
。
因为你问了一个例子:
if ($('input[id="user[privileges]"]').length > 0) {
$('#privileges button').each(function () {
if (parseInt($('input[id="user[privileges]"]').val()) & parseInt($(this).attr('value'))) {
$(this).button('toggle');
}
});
}
在给定隐藏字段的位掩码值的情况下,使用jQuery填充按钮的状态:
none
= 0
user
= 1
administrator
= 2
user
+ administrator
= 3