Java中的按位操作或on(双精度)不可能,JavaScript中可能

Java中的按位操作或on(双精度)不可能,JavaScript中可能,java,javascript,numbers,double,bitwise-or,Java,Javascript,Numbers,Double,Bitwise Or,以下是Google Chrome Javascript控制台的输出。 以下是来自DrJava控制台的输出。 我的Javascript代码是 (baseCPUCyclesPerIteration - CPUCyclesTotalRoundoff) | 0 如果两个变量都是整数,在Java中似乎可以编译,但在javascript中显然是双精度的。即使 basecpucyclesperation的类型显示“数字” 结果很明显,它是一个双重数据类型。我不明白为什么在Javascript中按位或0可

以下是Google Chrome Javascript控制台的输出。

以下是来自DrJava控制台的输出。

我的Javascript代码是

(baseCPUCyclesPerIteration - CPUCyclesTotalRoundoff) | 0
如果两个变量都是整数,在Java中似乎可以编译,但在javascript中显然是双精度的。即使

basecpucyclesperation的类型
显示
“数字”

结果很明显,它是一个双重数据类型。我不明白为什么在Javascript中按位
或0
可以在double上工作,但在Javadouble上不工作

似乎
|0
的目的只是修剪双精度数据类型中的小数点。我猜在Java中,等价物将是
(int)
(long)
强制转换,这是正确的吗?或者按位的
|0
比javascript中的小数点微调做得更多

编辑:
ya
|0
不只是修剪javascript,而是运行这个<代码>8899811111.111113453456754645 | 0返回
309876519


(虽然我通过了双限lol仍然试图在javascript中计算它,但我猜这就是溢出发生的地方)。

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

为了解释您看到的溢出,我们可以看看Javascript如何将数字转换为int32的规范:

ToInt32的抽象操作将其参数转换为范围内的2^32个整数值之一−2^31到2^31−1,包括在内。此抽象操作的功能如下:

  • 让number作为对输入参数调用ToNumber的结果
  • 如果数字为NaN,+0,−0, +∞, 或−∞, 返回+0
  • 设posInt为符号(数字)*楼层(abs(数字))
  • 设int32位为posInt模2^32;也就是说,具有正号且大小小于2^32的数字类型的有限整数值k,使得posInt和k的数学差在数学上是2^32的整数倍
  • 如果int32bit大于或等于2^31,则返回int32bit− 2^32,否则返回INT32位
  • 所以,为了重现这种行为,你必须重现这种逻辑

    编辑:以下是Mozilla的Rhino引擎在Java中的工作方式:(根据用户3435580提供的github链接)


    它们以不同的方式处理类型(您的问题似乎是合理的,只是说:p,比较它们令人困惑),因为在Java中,按位运算符只能应用于基本整数类型。。。这是由语言定义的。
    |0
    与Java中的
    (int)
    (long)
    转换相同吗?不知道,但最好使用
    parseInt()
    (JavaScript)imho。否则是的,您将在Java中强制转换以删除小数。但是要注意,您需要一个
    long
    来处理所有的
    double
    ,因为
    double
    中可能的整数值大于
    int
    supportsya
    |0
    在javascript中不只是修剪的值,而是运行了这个
    8899811111.111113453456754645 | 0
    返回
    309876519
    (虽然我通过了双重限制lol仍试图用javascript计算它,但我猜这就是溢出发生的地方)。我将如何复制
    19981111156.111113453456754645
    ,它给出的
    -1493725324
    可能不会发生,它会变得那么大,但只是为了安全起见。是的,它似乎在32位范围内溢出。在Java
    (int)19981111156.11111 3453456754645
    中给出了
    2147483647
    似乎Java在最大int处切断了值。我更新了我的答案,用规范的话解释了JavaScript中的这种溢出行为。似乎是这样,是的,这就是答案
    toInt32(19981111156.11111 3453453456754645)
    变成
    -1493725324
    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;
    }