以下是Google Chrome Javascript控制台的输出
以下是DrJava Java控制台的输出
我的Javascript代码是
(baseCPUCyclesPerIteration - CPUCyclesTotalRoundoff) | 0
如果两个变量都是整数但似乎在javascript中是双倍的,那么似乎在Java中编译得很好。即使
typeof baseCPUCyclesPerIteration
显示"number"
结果很明显它是双数据类型。我不明白为什么按位OR 0
适用于Javascript中的double,但不适用于Java double。
似乎| 0
的目的只是修剪double数据类型中的小数点。我在Java中猜测等效的(int)
或(long)
演员是否正确?或按位| 0
做更多,然后只是修改javascript中的小数点?
编辑:
雅| 0
不只是修改javascript只是运行这个。 8899811111.111113453456754645 | 0
回来309876519
(虽然我通过了双限制lol仍然试图在javascript中计算它,我猜这是溢出发生的地方)。
答案 0 :(得分:2)
在javascript中,所有按位运算符都会将十进制数转换为32位整数。对于正数,它的作用类似于floor
,对于负数,它的作用类似ceil
。 |0
或~~
之类的内容通常用作在JavaScript中将数字转换为整数的技巧。
为了解释您所看到的溢出,我们可以查看Javascript如何将数字转换为int32的规范:http://es5.github.io/#x9.5
抽象操作ToInt32将其参数转换为-2 ^ 31到2 ^ 31-1范围内的2 ^ 32个整数值之一。这个抽象操作的功能如下:
- 让 number 成为在输入参数上调用ToNumber的结果。
- 如果数字是NaN,+ 0,-0,+∞或-∞,则返回+0。
- 让 posInt 为标志(数字)*楼层(绝对(数字))。
- 让 int32bit posInt modulo 2 ^ 32;也就是说,数字类型的有限整数值k具有正号并且幅度小于2 ^ 32,使得 posInt 和k的数学差异在数学上是2 ^ 32的整数倍。
- 如果 int32bit 大于或等于2 ^ 31,则返回 int32bit - 2 ^ 32,否则返回 int32bit 。
醇>
因此,要重现此行为,您必须重现此逻辑。
编辑:以下是Mozilla的Rhino引擎在Java中的表现:(根据user3435580提供的github链接)
public static int toInt32(double d) {
int id = (int)d;
if (id == d) {
// This covers -0.0 as well
return id;
}
if (d != d
|| d == Double.POSITIVE_INFINITY
|| d == Double.NEGATIVE_INFINITY)
{
return 0;
}
d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
double two32 = 4294967296.0;
d = Math.IEEEremainder(d, two32);
// (double)(long)d == d should hold here
long l = (long)d;
// returning (int)d does not work as d can be outside int range
// but the result must always be 32 lower bits of l
return (int)l;
}