javascript中的逻辑移位如何工作

时间:2018-12-03 05:46:04

标签: javascript logical-operators bit-shift

逻辑移位的工作方式不同于其他语言。

var value = 1543812808507000000
var lowBits = value >>> 0

这是JavaScript代码。结果是3804366080。但是当我们用java或c开发此逻辑时,结果是3804366016。

哪个是正确的? javascript如何进行逻辑移位?

enter image description here

1 个答案:

答案 0 :(得分:3)

根据mozilla JS reference

  

MAX_SAFE_INTEGER常数的值为9007199254740991(9,007,199,254,740,991或〜9四千万分之一)。该数字背后的原因是,JavaScript使用IEEE 754中指定的双精度浮点格式数字,并且只能安全地表示-(2 53 -1)和2 53 < / sup>-1。

已经在注释中指出,您输入的1543812808507000000大于最大的安全整数。

因此,四舍五入发生在JavaScript端。

相比之下,C和Java都使用(精确)积分数学(低于C版本):

unsigned long long n = 1543812808507000000ULL;
n &= 0x00000000ffffffffULL;
printf("%llu\n", n);

替代计算:

n %= 0x0000000100000000ULL;

因此,C / Java输出在数学上是正确的。

您也很有可能使用浮点数学在C语言中产生相同的结果:

uint64_t n64 = 1543812808507000000ULL;
double d = n64;      // on conversion, rounding occurs!
uint32_t n32 = d;    // back to 32 bit, most significant bits dropped
printf("%lu\n", (unsigned long)n32);

出于完整性考虑:IEEE754描述了不同的舍入算法,并且C标准不强制要求特定的算法-实际上,它甚至根本不强制要求IEEE754。但是由于JS和C都直接使用相同的基础硬件(并且所有现代硬件都遵循IEEE754并具有相同的默认舍入),所以这没有实际意义。

如果您对演员表感到疑惑:uint32_t很可能被typedef编辑为unsigned int,但不一定(可以是{{1} }甚至unsigned long都符合C标准。但是,对于unsigned short,C要求覆盖一个范围,这样我们至少需要 32位,因此通过强制转换并使用unsigned long格式说明符,可以避免由于以下原因导致的未定义行为:格式说明符和数据类型不匹配,而不会改变结果。