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

时间:2017-06-29 13:22:19

标签: javascript

任何人都可以解释一下:

  • 为什么双按位不是为了无限returns 0

    ~~Infinity //return 0
    
  • 引擎盖下发生了什么?

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

1 个答案:

答案 0 :(得分: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;
}

打印:

7ff0000000000000
800fffffffffffff
7ff0000000000000

作为MDN notes

  

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

     

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

根据11.4.8 in ES5,我们有:

  

11.4.8按位非运算符(〜)

     

生产UnaryExpression : ~ UnaryExpression的评估如下:

     
      
  • expr成为评估UnaryExpression
  • 的结果   
  • oldValue成为ToInt32(GetValue(expr))
  •   
  • 返回对oldValue应用按位补码的结果。结果是带符号的32位整数。
  •   

ToInt32(Infinity) is +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