¿Cuál es el significado de double tilde ( ~ ~ ) en Java?


Al navegar por el código fuente de Guava, me encontré con la siguiente pieza de código (parte de la implementación de hashCode para la clase interna CartesianSet):

int adjust = size() - 1;
for (int i = 0; i < axes.size(); i++) {
    adjust *= 31;
    adjust = ~~adjust;
    // in GWT, we have to deal with integer overflow carefully
}
int hash = 1;
for (Set<E> axis : axes) {
    hash = 31 * hash + (size() / axis.size() * axis.hashCode());

    hash = ~~hash;
}
hash += adjust;
return ~~hash;

Ambos de adjust y hash son int s. Por lo que sé sobre Java, ~ significa negación bitwise, por lo que adjust = ~~adjust y hash = ~~hash deben dejar las variables sin cambios. Ejecutando la prueba pequeña (con aserciones habilitadas, por supuesto),

for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
    assert i == ~~i;
}

, Confirma esto. Suponiendo que los chicos de guayaba saben lo que están haciendo, debe haber un razón para que hagan esto. La pregunta es ¿qué?

EDITAR Como se señaló en los comentarios, la prueba anterior no incluye el caso donde i es igual a Integer.MAX_VALUE. Dado que i <= Integer.MAX_VALUE siempre es true, tendremos que comprobar ese caso fuera del bucle para evitar que se repita para siempre. Sin embargo, la línea

assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;

Produce la advertencia del compilador "Comparando expresiones idénticas", que prácticamente lo clava.

Author: dimo414, 2015-04-20

1 answers

En Java, no significa nada.

Pero ese comentario dice que la línea es específicamente para GWT, que es una forma de compilar Java a JavaScript.

En JavaScript, los enteros son como dobles que actúan como enteros. Tienen un valor máximo de 2^53, por ejemplo. Pero los operadores bitwise tratan los números como si fueran de 32 bits, que es exactamente lo que quieres en este código. En otras palabras, ~~hash dice "tratar hash como un número de 32 bits" en JavaScript. Específicamente, descarta todos pero los 32 bits inferiores (ya que los operadores ~ solo miran los 32 bits inferiores), que es idéntico a cómo funciona el desbordamiento de Java.

Si no tuviera eso, el código hash del objeto sería diferente dependiendo de si se evalúa en Java-land o en JavaScript land (a través de una compilación GWT).

 240
Author: yshavit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-19 23:12:50