1

这是来自 Google Chrome Javascript 控制台的输出。
http://i.stack.imgur.com/gefcZ.png

这是 DrJava Java 控制台的输出。
http://i.stack.imgur.com/bQ7hS.png

我的 Javascript 代码是

(baseCPUCyclesPerIteration - CPUCyclesTotalRoundoff) | 0

如果两个变量都是整数,则似乎在 Java 中编译得很好,但显然它们在 javascript 中是双精度的。虽然

typeof baseCPUCyclesPerIteration揭示"number"

结果很明显它是一个双重数据类型。我不明白为什么按位OR 0适用于 Javascript 中的双精度,但不适用于 Java 双精度。

似乎的目的| 0只是修剪双数据类型中的小数点。我猜Java中的等价物将是(int)(long)强制转换这是正确的吗?或者按位| 0做的不仅仅是修剪javascript中的小数点?

编辑:你| 0不只是在javascript中修剪只是运行了这个。8899811111.111113453456754645 | 0回来了309876519
(虽然我通过了双重限制,但 lol 仍然尝试在 javascript 中计算它,我猜这是发生溢出的地方)。

4

1 回答 1

2

在 javascript 中,所有位运算符都会将十进制数转换为 32 位整数。它的作用类似于floor正数和ceil负数。诸如|0or之类的东西~~经常被用作在 JavaScript 中将数字转换为整数的技巧。

为了解释您看到的溢出,我们可以查看 Javascript 如何将数字转换为 int32 的规范: http: //es5.github.io/#x9.5

抽象操作 ToInt32 将其参数转换为 -2^31 到 2^31-1 范围内的 2^32 个整数值之一。这个抽象操作的作用如下:

  1. number为对输入参数调用 ToNumber 的结果。
  2. 如果number为 NaN、+0、-0、+∞ 或 -∞,则返回 +0。
  3. posInt为 sign(number) * floor(abs(number))。
  4. int32bitposInt模 2^32;也就是说,具有正号且幅度小于 2^32 的 Number 类型的有限整数值 k,使得posInt和 k 的数学差在数学上是 2^32 的整数倍。
  5. 如果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;
}
于 2014-03-23T01:12:08.083 回答