4

当我在这里运行此代码时:

console.log(255<<24==0xff000000)

我得到的是假而不是真的。这是为什么?

4

4 回答 4

4

因为 JavaScript 数字是 IEEE-754 双精度浮点数,而不是 32 位整数。一个大的正数(十进制 4,278,190,080)也是如此0xff000000,而不是一个负数,因为它是一个有符号的 32 位整数。

当你这样做<<时,被移动的数字(在你的情况下为 255)会临时转换为有符号的 32 位整数,以便进行位移:

000000000000000000000000011111111
^\ /
| \----- 有效位----/
+------- 符号位

当我们向左移动 24 位时,符号位中会出现 1 位:

11111111000000000000000000000000
^\ /
| \----- 有效位----/
+------- 符号位

...因此结果最终为负数,并变回负数 IEEE-754 数(-16,777,216 十进制)。-16,777,216 不等于 4,278,190,080。

(IEEE-754 双精度浮点数的范围大于 32 位有符号整数的范围。我不太确定为什么我觉得这是相关的,但我确实如此,所以我想我会把它留在答案中...)

于 2013-08-03T16:36:32.153 回答
2

这样看。这对您来说应该很直观:

255<<24 == 0xff000000<<0          // Returns true

位运算符适用于整数而不是数字类型。将其视为等同于其他语言中的类型转换,您碰巧将较大大小的数字放入较小的数字中,而您会丢失东西...

由于采用了浮点格式,Javascript 牺牲了精度以允许更大的数字。

所以 Javascript 会失去 0xff000000 的精度,就像 255 一样。

于 2013-08-03T16:41:54.747 回答
1

如 TJ 所述,javascript 中的按位运算将数字转换为有符号的32 位整数,因此您只有 31 位可以安全地与十六进制文字进行比较。如果您想保留您真正想要的无符号数(而不是将您的十六进制文字转换为相同的负数),请执行以下操作:

255 * (1 << 24) == 0xff000000
于 2015-05-03T05:03:46.530 回答
0

0xff000000不指定 32 位整数的位,而是以十六进制为基数的实数。例如0xff0000000000000000000004.932417344027687e+27

除了>>>给出操作数 int32 语义外,所有按位运算都>>>给出 uint32 语义。

因此,您可以将| 0其用作一种int声明或(int)强制转换:

255 << 24 == (0xff000000 | 0)
true
于 2013-08-03T18:55:37.980 回答