在JavaScript中,为什么~~ Infinity评估为0?

luk*_*uke 4 javascript

谁能解释一下:

  • 为什么双按位不适用于Infinity returns 0

    ~~Infinity //return 0
    
    Run Code Online (Sandbox Code Playgroud)
  • 引擎盖下发生了什么?

  • 在javascript中Infinity的二进制表示是什么?

Sin*_*nür 5

因为您没有在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;
}
Run Code Online (Sandbox Code Playgroud)

这打印:

7ff0000000000000
800fffffffffffff
7ff0000000000000
Run Code Online (Sandbox Code Playgroud)

正如MDN所说:

按位运算符将它们的[sic]操作数视为一组32位(零和1),而不是十进制,十六进制或八进制数....按位运算符在这种二进制表示上执行操作,但它们返回标准的JavaScript数值.

...将最高有效(最左侧)位设置为1的值表示负数(二进制补码表示).

根据ES5中的11.4.8,我们有:

11.4.8按位NOT运算符(〜)

生产UnaryExpression : ~ UnaryExpression评估如下:

  • 让我们expr评估的结果UnaryExpression.
  • 我们oldValueToInt32(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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

00000000
FFFFFFFF
00000000
Run Code Online (Sandbox Code Playgroud)