Tengo el siguiente código Java:
long num = 3482085570325547757; // Discard all but the highest priority 31 bits int result = (int) (num >>> 33); // Returns 405368112Estoy tratando de hacer el equivalente en Javascript (usando el motor https://github.com/oracle/graaljs ), sin embargo, no me está dando el mismo resultado que el código Java:
const num = 3482085570325547757; // Discard all but the highest priority 31 bits const result = num >>> 33; // Returns 1281508608Pensé que podría tener que ver con la forma en que GraalJS almacena números internamente como enteros y dobles. También intenté transmitir explícitamente a int usando lo siguiente, pero también me dio un resultado diferente al código 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 1281508608En primer lugar, su ejemplo de Java no se compila. Los literales largos requieren un sufijo L (o l ):
long num = 3482085570325547757L;Entonces, JavaScript no puede almacenar ese número con total precisión.
const num = 3482085570325547757; console.log(num); // Displays 3482085570325547500 El entero máximo que puede almacenar es 9007199254740991 ( Number.MAX_SAFE_INTEGER ).
Usar BigInteger de Java como lo hizo así no funcionará, porque ya ha perdido precisión antes de crear BigInteger . Necesitaría usar una cadena para crear correctamente BigInteger (o BitInt de JavaScript, o el sufijo n ).
Sin embargo, eso tampoco es realmente útil, porque >>> no tiene sentido en ellos. Cita de la documentación de BigInteger de Java:
El operador de desplazamiento a la derecha sin signo (>>>) se omite ya que esta operación solo tiene sentido para una palabra de tamaño fijo y no para una representación que tiene conceptualmente un número infinito de bits de signo virtuales principales.
Lo mismo es cierto para BigInt de JavaScript.
Sin embargo, puede usar el operador normal de desplazamiento a la derecha ( >> ) con BigInt :
const num = BigInt("3482085570325547757"); const bigIntResult = num >> BigInt(33); const result = Number(bigIntResult); // Convert to normal numberO
const num = 3482085570325547757n; const bigIntResult = num >> 33n; const result = Number(bigIntResult); // Convert to normal number O el método shiftRight() de BigInteger de Java (no probado, porque no tengo la configuración de GraalJS):
const BigInteger = Java.type('java.math.BigInteger'); const num = new BigInteger("3482085570325547757"); const result = num.shiftRight(33).intValue();Ver también: