ECMAScript bit operator

Wei yun suozhe shi zai shu zi di ceng (ji shi biaozhi shu zi de 32 ge shu wei) jingxing cunzai de.

Chongxin renwen zhen shu

ECMAScript zhen shu you liang zhong leixing, jici youxian zhen shu (xuanze neng yong zheng shu he fu shu) he wuxian zhen shu (zhi xuan neng yong zheng shu). Zai ECMAScript zhong, suanmei ge zhen shu miandian liu (ji shi biaozhi zhen shu de 32 ge shu wei) jingxing cunzai de. Zhe me zhege me yao yanshi na me ne?

Youxian zhen zheng zhen shi yong 31 wei biaozhi zhen shu de zhi, yong di 32 wei biaozhi zhen shu de hao, 0 biaozhi zheng shu, 1 biaozhi fu shu. Zhi shu fanwei cong -2147483648 dao 2147483647.

Keyi yi liang butong de fangshi cunchou erjinzhi fanyuan de youxian zheng zhen, yi zhong yong yu cunchou zheng shu, yi zhong yong yu cunchou fu shu. Zheng shu shi yi wei zhen erjinzhi fanyuan cunchou de, qian 31 wei de meiyi wei dou biaozhi 2 de mian, cong di 1 wei (wei 0) kaishi, biaozhi 20,di 2 wei (wei 1) biaozhi 21。Mei yongdao de wei yong 0 tianchong, jia zhi huiwun. Li ming, tiaoxian shi shu 18 de biaozhishi.

32 biyina wakilcin girmekle ifade edile bir binomiyal san

18 de erjinzhi banben zhiyou qian 5 wei, ta men shi zhe ge shu de youxiao wei. Ba shu huanzhuan cheng erjinzhi zifuchuan, jiu neng kanjian youxiao wei:

var iNum = 18;
alert(iNum.toString(2));	//yinchu "10010"

Dannin gidiin yin dake yin "10010", kuma yin dake bai 32 jiyin 18. Zaiwan de xiaowei bing bu zhuyao, yinwei zhi xiang shi yong qian 5 wei jiu neng queding zhe ge shisan jishu zhi. Ru tiaoxian shuo, gaozai zhe:

5 biyina wakilcin girmekle ifade edile bir san 18

负数也存储为二进制代码,不过采用的形式是二进制补码。计算数字二进制补码的步骤有三步:

  1. 确定该数字的非负版本的二进制表示(例如,要计算 -18的二进制补码,首先要确定 18 的二进制表示)
  2. 求得二进制反码,即要把 0 替换为 1,把 1 替换为 0
  3. 在二进制反码上加 1

要确定 -18 的二进制表示,首先必须得到 18 的二进制表示,如下所示:

0000 0000 0000 0000 0000 0000 0001 0010

接下来,计算二进制反码,如下所示:

1111 1111 1111 1111 1111 1111 1110 1101

最后,在二进制反码上加 1,如下所示:

1111 1111 1111 1111 1111 1111 1110 1101
                                      1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110

因此,-18 的二进制表示即 1111 1111 1111 1111 1111 1111 1110 1110。记住,在处理有符号整数时,开发者不能访问 31 位。

有趣的是,把负整数转换成二进制字符串后,ECMAScript 并不以二进制补码的形式显示,而是用数字绝对值的标准二进制代码前面加负号的形式输出。例如:

var iNum = -18;
alert(iNum.toString(2));	//输出 "-10010"

这段代码输出的是 "-10010",而非二进制补码,这是为避免访问位 31。为了简便,ECMAScript 用一种简单的方式处理整数,使得开发者不必关心它们的用法。

另一方面,无符号整数把最后一位作为另一个数位处理。在这种模式中,第 32 位不表示数字的符号,而是值 231Daga baya, saboda wannan bit na saba, wakilin noma mai noma na kowace na 0 zuwa 4294967295. Don kowace na intan da ya kai 2147483647, wakilin noma mai noma ya fi kowane wakilin noma mai noma, amma kowace na ya kai 2147483647 ya haɗa da bit 31 (a cikin wakilin noma mai noma, wannan bit kuma ya zama 0).

Duba wakilin noma mai noma da a samar da rubutu, yana cire da kawai bit na wakilin noma.

注意:Kanan kowace na wakilin noma na intan suna da farin cikin wakilin noma mai noma. Kawai wakilin noma na bit ECMAScript ke iya samar da wakilin noma mai noma.

Bit wakilin NOT

Bit wakilin NOT da a kanan wakilin na ~ (nakar da), wanda ke daga cikin wakilin ikoma da kuma wakilin noma na binary wanda ke karkashin ECMAScript.

wei yunshu NOT shi san bu de chuli guocheng:

  1. ba yunshu shu zhuan huan cheng 32 wei shu zi
  2. ba er jin shu zhuan huan cheng ta de er jin fan ma
  3. ba er jin shu zhuan huan cheng wu dian shu

li bi:

var iNum1 = 25;		// 25 dengyu 00000000000000000000000000011001
var iNum2 = ~iNum1;	// huan zhi wei 11111111111111111111111111100110
alert(iNum2);		// chushu "-26"

wei yunshu NOT shi zhijiu shu zi qiu fu, ran hou jian 1, yin ci 25 bian -26. Yong li xia de fa fa ye neng huo dao tong yi de jieguo:

var iNum1 = 25;
var iNum2 = -iNum1 -1;
alert(iNum2);	// chushu "-26"

wei yunshu AND

wei yunshu AND you he hao (&) biaoshi, zhijiu shu zi de er jin xing yunshu. Ta ba mege shu zi zhong de shuwei dui li, yun hou yong li xia de gui ze dui tong yi weizhi shang de liang ge shuwei jinxing AND yunshu:

第一个数字中的数位 第二个数字中的数位 结果
1 1 1
1 0 0
0 1 0
0 0 0

li bi, dui shu zi 25 he 3 jinxing AND yunshu, maohao ru xia shi:

var iResult = 25 & 3;
alert(iResult);	// chushu "1"

25 he 3 jinxing AND yunshu de jieguo shi 1. Wei shenme? Fenxi ru xia:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001

kewa, zai 25 he 3 zhong, zhi you yi ge shuwei (wei 0) cangfang de dou shi 1, yin ci, qi ta shuwei shengcheng de dou shi 0, suoyi, jieguo wei 1.

wei yunshu OR

wei yunshu OR you haozi (|) biaoshi, ye shi zhijiu shu zi de er jin xing yunshu. Zai jisuan me wei shi, OR yunshu shi yong li xia de gui ze:

第一个数字中的数位 第二个数字中的数位 结果
1 1 1
1 0 1
0 1 1
0 0 0

zhen liangshi shi yong AND yunshu shi yong de li, dui 25 he 3 jinxing OR yunshu, maohao ru xia:

var iResult = 25 | 3;
alert(iResult);	// chushu "27"

25 da 3 jinxing OR yunshu de jieguo shi 27:

25 = 0000 0000 0000 0000 0000 0000 0001 1001
 3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
OR = 0000 0000 0000 0000 0000 0000 0001 1011

akewa, a kan yiya 2 kanimu, 4 kanamici a kanmu yige zai, zhexie kanmu bei chuanbo gei jieguo. Er jin hua ma 11011 dengyu 27.

位运算 XOR

位运算 XOR 由符号(^)表示,当然,也是直接对二进制形式进行运算。XOR 不同于 OR,当只有一个数位存放的是 1 时,它才返回 1。真值表如下:

第一个数字中的数位 第二个数字中的数位 结果
1 1 0
1 0 1
0 1 1
0 0 0

对 25 和 3 进行 XOR 运算,代码如下:

var iResult = 25 ^ 3;
alert(iResult);	//输出 "26"

25 和 3 进行 XOR 运算的结果是 26:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010

可以看出,在两个数字中,共有 4 个数位存放的是 1,这些数位被传递给结果。二进制代码 11010 等于 26。

左移运算

左移运算由两个小于号表示(<<)。它把数字中的所有数位向左移动指定的数量。例如,把数字 2(等于二进制中的 10)左移 5 位,结果为 64(等于二进制中的 1000000):

var iOld = 2;		//等于二进制 10
var iNew = iOld << 5;	//等于二进制 1000000 十进制 64

注意:在左移数位时,数字右边多出 5 个空位。左移运算用 0 填充这些空位,使结果成为完整的 32 位数字。

San 2 sol yana girmekle islem

注意:左移运算保留数字的符号位。例如,如果把 -2 左移 5 位,得到的是 -64,而不是 64。“符号仍然存储在第 32 位中吗?”是的,不过这在 ECMAScript 后台进行,开发者不能直接访问第 32 个数位。即使输出二进制字符串形式的负数,显示的也是负号形式(例如,-2 将显示 -10。)

有符号右移运算

有符号右移运算符由两个大于号表示(>>)。它把 32 位数字中的所有数位整体右移,同时保留该数的符号(正号或负号)。有符号右移运算符恰好与左移运算相反。例如,把 64 右移 5 位,将变为 2:

var iOld = 64;		//等于二进制 1000000
var iNew = iOld >> 5;	//等于二进制 10 十进制 2

同样,移动数位后会造成空位。这次,空位位于数字的左侧,但位于符号位之后。ECMAScript 用符号位的值填充这些空位,创建完整的数字,如下图所示:

San 64 imzali sag yana girmekle islem

无符号右移运算

无符号右移运算符由三个大于号(>>>)表示,它将无符号 32 位数的所有数位整体右移。对于正数,无符号右移运算的结果与有符号右移运算一样。

用有符号右移运算中的例子,把 64 右移 5 位,将变为 2:

var iOld = 64;		//等于二进制 1000000
var iNew = iOld >>> 5;	//等于二进制 10 十进制 2

对于负数,情况就不同了。

无符号右移运算用 0 填充所有空位。对于正数,这与有符号右移运算的操作一样,而负数则被作为正数来处理。

由于无符号右移运算的结果是一个 32 位的正数,所以负数的无符号右移运算得到的总是一个非常大的数字。例如,如果把 -64 右移 5 位,将得到 134217726。如何得到这种结果的呢?

要实现这一点,需要把这个数字转换成无符号的等价形式(尽管该数字本身还是有符号的),可以通过以下代码获得这种形式:

var iUnsigned64 = -64 >>> 0;

然后,用 Number 类型的 toString() 获取它的真正的位表示,采用的基为 2:

alert(iUnsigned64.toString(2));

这将生成 11111111111111111111111111000000,即有符号整数 -64 的二进制补码表示,不过它等于无符号整数 4294967232。

出于这种原因,使用无符号右移运算符要小心。