我的印象是,Javascript 中的 Number 类型根据 IEEE 浮点标准存储任何数字、整数或浮点数。如果是这样,那么为什么将一个数字与 0 进行按位或运算呢?
玩弄其他一些位操作,似乎在对浮点数应用位操作时,数字首先向 0 舍入,然后应用位操作(使用二进制补码表示而不是 IEEE 表示的数字)。这个对吗?
我的印象是,Javascript 中的 Number 类型根据 IEEE 浮点标准存储任何数字、整数或浮点数。如果是这样,那么为什么将一个数字与 0 进行按位或运算呢?
玩弄其他一些位操作,似乎在对浮点数应用位操作时,数字首先向 0 舍入,然后应用位操作(使用二进制补码表示而不是 IEEE 表示的数字)。这个对吗?
在 ECMAScript 5.1 中,所有按位运算都会将输入转换为 32 位整数,并返回一个 32 位整数。关于运算符^
,&
和|
,第 11.10 节说:
产生
A : A @ B
式@
是上述产生式中的位运算符之一,其评估如下:1) 令 lref 为评估 A 的结果。
2) 令 lval 为 GetValue(lref)。
3) 令 rref 为评估 B 的结果。
4) 令 rval 为 GetValue(rref)。
5) 令 lnum 为 ToInt32(lval)。
6) 设 rnum 为 ToInt32(rval)。
7) 返回将按位运算符@ 应用于lnum 和rnum 的结果。结果是一个带符号的 32 位整数。
请注意,在应用运算符之前,两边都应用了ToInt32 。
在语言级别,按位运算符只有浮点数和临时整数。
根据规范,通过执行抽象操作将浮点数转换为 32 位整数:
var n = (sign(number) * floor(abs(number))) % pow(2, 32);
if( n >= pow( 2, 31 ) ) {
return n - pow( 2, 32 );
}
else {
return n;
}
我必须强调,这个操作是抽象的,当然不是任何引擎都以上述方式完成的,所以不要从中得出任何性能考虑。(这也适用于任何其他规范操作)