javascript中对字符串的按位运算

时间:2014-03-05 23:59:28

标签: javascript binary

在javascript中,以下字符到二进制操作的测试打印0 676次:

var s = 'abcdefghijklmnopqrstuvwxyz';
var i, j;
for(i=0; i<s.length;i++){ for(j=0; j<s.length;j++){ console.log(s[i] | s[j]) }};

如果js正在使用字符串的实际二进制表示,我希望这里有一些非零值。

同样,测试字符串和整数的二进制操作,下面分别打印26 2550。 (选择255是因为它是二进制的11111111

var s = 'abcdefghijklmnopqrstuvwxyz';
var i; for(i=0; i<s.length;i++){ console.log(s[i] | 255) }
var i; for(i=0; i<s.length;i++){ console.log(s[i] & 255) }

javascript在这做什么?似乎javascript在二进制操作之前将任何字符串转换为false

备注

如果你在python中尝试这个,它会抛出一个错误:

>>> s = 'abcdefghijklmnopqrstuvwxyz'
>>> [c1 | c2 for c2 in s for c1 in s]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'str' and 'str'

但是这样的事情似乎work in php

3 个答案:

答案 0 :(得分:10)

在JavaScript中,当字符串与二元运算符一起使用时,它首先转换为数字。 ECMAScript规范的相关部分如下所示,以解释其工作原理。

Bitwise operators

  

生产A:A @ B,其中@是上述产品中的一个按位运算符,评估如下:

     
      
  1. 让lref成为评估A.
  2. 的结果   
  3. 让lval成为GetValue(lref)。
  4.   
  5. 让rref成为评估B.
  6. 的结果   
  7. 让rval为GetValue(rref)。
  8.   
  9. 让lnum成为ToInt32(lval)。
  10.   
  11. 设rnum为ToInt32(rval)。
  12.   
  13. 返回将按位运算符@应用于lnum和rnum的结果。结果是带符号的32位整数。
  14.   

ToInt32

  

抽象操作ToInt32将其参数转换为-231到231-1(含)范围内的2个 32 整数值之一。这个抽象操作的功能如下:

     
      
  1. 设number是输入参数上调用ToNumber的结果。
  2.   
  3. 如果number为NaN,+ 0,-0,+∞或-∞,则返回+0。
  4.   
  5. 让posInt为sign(number)* floor(abs(number))。
  6.   
  7. 让int32bit为posint modulo 2 32 ;也就是说,数字类型的有限整数值k具有正号并且在数量上小于2 32 ,使得posInt和k的数学差异在数学上是2 32的整数倍
  8.   
  9. 如果int32bit大于或等于2 31 ,则返回int32bit - 2 32 ,否则返回int32bit。
  10.   

内部ToNumber函数将为任何无法解析为数字的字符串返回NaN,而ToInt32(NaN)将给出0.因此在您的代码示例中,所有以字母作为操作数的按位运算符将计算为{{ 1}},这解释了为什么只打印0。

请注意0 | 0之类的内容将评估为'7' | '8',因为在这种情况下,用作操作数的字符串可以成功地转换为数字。

至于为什么Python中的行为不同,Python中没有任何隐式类型转换,因此任何未实现二元运算符的类型都会出现错误(使用7 | 8,{ {1}}等,而字符串不实现那些二元运算符。

Perl做了一些完全不同的事情bitwise operators are implemented for strings,它实际上将为每个字符串中的相应字节执行按位运算符。

如果您想使用JavaScript并获得与Perl相同的结果,则需要先使用str.charCodeAt将字符转换为其代码点,对结果整数执行按位运算符,然后使用{{ 3}}将结果数值转换为字符。

答案 1 :(得分:4)

如果JavaScript在非数字字符串上进行逐位运算并产生任何有意义的内容,我会感到惊讶。我想这是因为JavaScript中的任何按位运算符都将其操作数转换为32位整数,它只会将所有非数字字符串转换为0

我会用...

"a".charCodeAt(0) & 0xFF

那产生97,即“a”的ASCII码,这是正确的,因为它被一个设置了所有位的字节屏蔽掉。

请记住,因为在其他语言中,事情很好用,但在JavaScript中并非总是如此。我们谈论的是一种在很短的时间内构思和实施的语言。

答案 2 :(得分:3)

JavaScript正在使用类型强制,当您尝试对它们执行数字操作时,它允许它尝试自动将字符串解析为数字。解析后的值可能为0或更高NaN。这显然不会为您提供您想要获得的信息。

我认为您正在寻找的是charCodeAt,这将允许您获取字符串中字符的数字Unicode值,并且可能是将数值转换回的互补fromCodePoint一个角色。