在 Javascript 中,逻辑移位的工作方式与其他语言不同。
var value = 1543812808507000000
var lowBits = value >>> 0
这是javascript代码。结果是3804366080。但是当我们用java或c开发这个逻辑时,结果是3804366016。
哪个是正确的?逻辑移位在 JS 中是如何工作的?
最佳答案
根据 mozilla JS reference :
The MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion). The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent numbers between -(253 - 1) and 253 - 1.
如评论中所述,您输入的数字 1543812808507000000 大于最大安全整数。
因此舍入发生在 JavaScript 端。
相比之下,C 和 Java 都使用(精确的)积分数学(低于 C 版本):
unsigned long long n = 1543812808507000000ULL;
n &= 0x00000000ffffffffULL;
printf("%llu\n", n);
替代计算:
n %= 0x0000000100000000ULL;
因此 C/Java 输出在数学上是正确的。
您也很有可能在 C 中使用 float 学产生相同的结果:
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
,但不一定(可以是 unsigned long
甚至 unsigned short
,根据 C 标准都是合法的)。但是,对于 unsigned long
,C 要求覆盖一个范围,因此我们至少 需要 32 位,因此通过强制转换和使用 %lu
格式说明符我们避免了由于格式说明符和数据类型不匹配而导致的未定义行为而不改变结果。
关于javascript - 逻辑移位如何在 javascript 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53588114/