有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Javascript(GraalJS)与Java中未签名的右移>>>>

我有以下Java代码:

long num = 3482085570325547757;
// Discard all but the highest priority 31 bits
int result = (int) (num >>> 33); // Returns 405368112

我试图用Javascript(使用https://github.com/oracle/graaljs引擎)执行等效操作,但是,它并没有给出与Java代码相同的结果:

const num = 3482085570325547757;
// Discard all but the highest priority 31 bits
const result = num >>> 33; // Returns 1281508608

我想这可能与GraalJS内部将数字存储为整数和双倍的方式有关?我也尝试使用下面的代码显式转换为int,但它也给了我与Java代码不同的结果:

const Long = Java.type('java.lang.Long');
const String = Java.type('java.lang.String');
const BigInteger = Java.type('java.math.BigInteger');
const num = 3482085570325547757;
// Discard all but the highest priority 31 bits
const result = BigInteger.valueOf(num >>> 33).intValue(); // Returns 1281508608

共 (1) 个答案

  1. # 1 楼答案

    首先,您的Java示例没有编译。长文本需要L(或l)后缀:

    long num = 3482085570325547757L;
    

    然后,JavaScript无法完全准确地存储该数字

    const num = 3482085570325547757;
    console.log(num); // Displays 3482085570325547500
    

    它可以存储的最大整数是9007199254740991(Number.MAX_SAFE_INTEGER

    像您那样使用Java的BigInteger是行不通的,因为您在创建BigInteger之前已经失去了准确性。您需要使用字符串来正确创建BigInteger(或JavaScript的BitInt,或n后缀)

    然而,这也没有真正的帮助,因为>>>对它们没有意义。引自Java的^{} documentation

    The unsigned right shift operator (>>>) is omitted since this operation only makes sense for a fixed sized word and not for a representation conceptually having an infinite number of leading virtual sign bits.

    JavaScript的BigInt也是如此

    但是,您可以将正常右移(>>)运算符与BigInt一起使用:

    const num = BigInt("3482085570325547757");
    const bigIntResult = num >> BigInt(33); 
    const result = Number(bigIntResult); // Convert to normal number
    

    const num = 3482085570325547757n;
    const bigIntResult = num >> 33n; 
    const result = Number(bigIntResult); // Convert to normal number
    

    或者Java的BigIntegershiftRight()方法(未经测试,因为我没有GraalJS设置):

    const BigInteger = Java.type('java.math.BigInteger');
    const num = new BigInteger("3482085570325547757");
    const result = num.shiftRight(33).intValue();
    

    另见: