因为JavaScript不操作数字的底层位模式。
你不能在JavaScript中执行以下C代码的等效操作:
#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
double x = HUGE_VAL;
uint64_t y = *((uint64_t *) &x);
printf("%016" PRIx64 "\n", y);
printf("%016" PRIx64 "\n", ~y);
printf("%016" PRIx64 "\n", ~~y);
return 0;
}
这将打印:
7ff0000000000000
800fffffffffffff
7ff0000000000000
作为
MDN笔记 所述:
按位运算符将其操作数视为一组32位(零和一)而不是十进制、十六进制或八进制数字。... 按位运算符在这些二进制表示上执行其操作,但返回标准的JavaScript数值。
... 最高有效位(最左侧)设置为 1 的值表示负数(二进制补码表示)。
根据
ES5中的11.4.8,我们有:
11.4.8 按位非运算符(~)
产生式 UnaryExpression : ~ UnaryExpression
的求值过程如下:
- 令
expr
为求值结果的 UnaryExpression
。
- 令
oldValue
为 ToInt32(GetValue(expr))
。
- 返回将 oldValue 应用按位补码的结果。结果是一个有符号的32位整数。
ToInt32(Infinity)
的结果是 +0
。第一个 ~
将其变成了 0xffffffff
。第二个 ~
反转所有位,变成了零。
也就是说,它执行了以下等效于C代码的操作:
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
int main(void) {
double x = HUGE_VAL;
uint32_t y = x;
printf("%08X\n", y);
printf("%08X\n", ~y);
printf("%08X\n", ~~y);
return 0;
}
输出:
00000000
FFFFFFFF
00000000
~Infinity
等于-1
。 - Evan Trimboli~
中使用了ToInt32
,而在9.5中描述了NaN、+0、-0、+inf或-inf被转换为+0
。 - Patrick Barr