JavaScript的位操作符

位运算用在最基本的层次,是直接用内存中的数值的位来操作数值。

js所有的数字都以IEEE-754 64位存储,但在实际运算中,我们是操作32位的,
这个过程是这样的。

64位存储-->32位操作-->64位存储


js中的数值分为有符号数和无符号数,区别就在于第32位数字用来表示符号还是数值,用来表示符号就是有符号数,可以表示正负数;没有符号就是无符号数,只有正数,但可以表示更大的值。


有符号位整数

32位中的前31位用来表示数值,而第32位用于表示数值的符号,0代表正数、1代表负数。

负数是以二进制补码的形式存储的,其中正数和负数的转化形式是这样的。

  1. 首先是将这位数的绝对值转化为二进制
    (如-18绝对值的二进制是0000 0000 0000 0000 0000 0000 0001 0010 )
  2. 求二进制补码,即0变成1,1变成0(1111 1111 1111 1111 1111 1111 1110 1101)
  3. 最后是反码加一变成补码,即求结果(1111 1111 1111 1111 1111 1111 1110 1110 )

ECMAScript会隐藏这些细节,一般我们会看到在二进制前面加一个负号来表示负数

var num=-18;
console.log(num.toString(2))
// "-10010"
  • 按位非(NOT)

操作符是(~),执行这个操作的结果就是返回数值的反码

var num1 = 25;
// 00000000000000000000000000011001
var num2 = ~num1; 
// 11111111111111111111111111100110
console.log(num2)
// -26

类似的,我们用负号运算,这体现了按位非的本质。

var num1 = 25;
var num2 = -num1 - 1;
console.log(num2)
// -26
  • 按位与(AND)

操作符是(&),规则就是将两个数值对齐,然后按照下面的规则返回结果

第一个数值的值 第二个数值的值 结果
1 1 1
1 0 0
0 1 0
0 0 0

简而言之,按位与操作就是两个数值都是1的时候才返回1,否则返回0;

var result = 25 & 3;
console.log(result);
// 1
//  25 = 1 1 0 0 1 
//   3 = 0 0 0 1 1
//       ↓ ↓ ↓ ↓ ↓
// AND = 0 0 0 0 1
  • 按位或(OR)

第一个数值的值 第二个数值的值 结果
1 1 1
1 0 1
0 1 1
0 0 0

操作符是(|),规则遵循下表

第一个数值的值 第二个数值的值 结果
1 1 1
1 0 1
0 1 1
0 0 0

简而言之,按位或就是有一位数值是1就返回1,只有全为0的时候才返回0。

var result = 25 | 3;
console.log(result);
// 27
// 25 = 1 1 0 0 1 
//  3 = 0 0 0 1 1
//      ↓ ↓ ↓ ↓ ↓
// OR = 1 1 0 1 1
  • 按位异或(XOR)

第一个数值的值 第二个数值的值 结果
1 1 0
1 0 1
0 1 1
0 0 0

操作符是(^),操作数是两个,规则如下:

第一个数值的值 第二个数值的值 结果
1 1 0
1 0 1
0 1 1
0 0 0

按位异或和按位或的不同之处就在,当两个数值都是1的时候,前者返回0而后者返回1。其他的方面两个都是一样的,所以按位异或就是当只有一个1的时候才返回1。

var result = 25 ^ 3;
console.log(result);
// 26
//  25 = 1 1 0 0 1 
//   3 = 0 0 0 1 1
//       ↓ ↓ ↓ ↓ ↓
// XOR = 1 1 0 1 0
  • 左移

操作符是两个小于号(<<),左移表示将指定二进制数向左移动指定的位数。比如下面例子将2向左移动5位

var value = 2;
var result = value << 5;
console.log(result);
// 64
// 00010 → 0001000000 

向左移位后,右侧会多出5个空位,这些空位将会以0填充。
注意,左移不会影响符号位,意思就是符号位是独立的,不会改变。例如-2左移5位,得到的是-64而非64。

var value = -2;
var result = value << 5;
console.log(result);
// -64
  • 有符号右移

操作符是两个大于号(>>),右移表示将指定二进制数向右移动指定的位数。比如下面例子将64向右移动5位

var value = 64;
var result = value >> 5;
console.log(result);
// 2
// 00000000000000000000000001000000
// 00000000000000000000000000000010

同样的,在位移过程中,左侧会出现空位,这时候会用符号位的值来填充所有空位,以便得到一个完整的值。

var value = -64;
var result = value >> 5;
console.log(result);
// -2
// 11111111111111111111111110000000
// 11111111111111111111111111111110
  • 无符号右移

无符号右移的操作符是3个大于号(>>>),
这个操作符会将所有32位数值向右移动,右侧空位以0填充。

var value1 = 64;
var result1 = value1 >>> 5;
console.log(result1);
// 2

var value2 = -64;
var result2 = value2 >>> 5;
console.log(result2);
// 134217726
// 
// 11111111111111111111111111100000
// 无符号左移5位
// 00000111111111111111111111111110

无符号右移会把负数的二进制码当成正数的二进制码,所以这会导致负数的无符号右移结果特别大。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容