javascript 中的逻辑移位如何工作
How does logical shift work in javascript
在 Javascript 中,逻辑移位的工作方式与其他语言不同。
var value = 1543812808507000000
var lowBits = value >>> 0
这是java脚本代码。结果是3804366080。但是当我们在java或c中开发这个逻辑时,结果是3804366016。
哪个是正确的?逻辑移位在 JS 中如何工作?
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 大于最大安全整数。
因此舍入发生在Java脚本端。
相比之下,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
,但不一定(可能unsigned long
甚至 unsigned short
,根据 C 标准都是合法的)。但是,对于 unsigned long
,C 要求覆盖一个范围,因此我们至少需要 32 位,因此通过强制转换和使用 %lu
格式说明符,我们可以避免未定义由于格式说明符和数据类型不匹配而导致的行为而不改变结果。
在 Javascript 中,逻辑移位的工作方式与其他语言不同。
var value = 1543812808507000000
var lowBits = value >>> 0
这是java脚本代码。结果是3804366080。但是当我们在java或c中开发这个逻辑时,结果是3804366016。
哪个是正确的?逻辑移位在 JS 中如何工作?
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 大于最大安全整数。
因此舍入发生在Java脚本端。
相比之下,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
,但不一定(可能unsigned long
甚至 unsigned short
,根据 C 标准都是合法的)。但是,对于 unsigned long
,C 要求覆盖一个范围,因此我们至少需要 32 位,因此通过强制转换和使用 %lu
格式说明符,我们可以避免未定义由于格式说明符和数据类型不匹配而导致的行为而不改变结果。