Co oznacza Podwójna tylda ( ~ ~ ) w języku Java?

Przeglądając kod źródłowy Guava, natknąłem się na następujący fragment kodu (część implementacji hashCode dla klasy wewnętrznej 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;

Zarówno adjust jak i hashints. z tego, co wiem o Javie, ~ oznacza bitową negację, więc adjust = ~~adjust i hash = ~~hash powinny pozostawić zmienne bez zmian. Uruchamianie małego testu (oczywiście z włączonymi twierdzeniami),

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

Potwierdza to. Zakładając, że faceci z guawy wiedzą, co robią, musi być powód, dla którego to zrobili. Pytanie brzmi: co?

EDIT jak zaznaczono w komentarzach, powyższy test nie uwzględnia przypadku, w którym i równa się Integer.MAX_VALUE. Ponieważ {[13] } jest zawsze prawdziwe, będziemy musieli sprawdzić ten przypadek poza pętlą, aby zapobiec zapętleniu go w nieskończoność. Jednak linia

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

Daje ostrzeżenie kompilatora "porównywanie identycznych wyrażeń", które w zasadzie go gwoździuje.

Author: dimo414, 2015-04-20

1 answers

W Javie to nic nie znaczy.

Ale ten komentarz mówi, że linia jest specjalnie dla GWT, który jest sposobem kompilacji Javy do JavaScript.

W JavaScript liczby całkowite są jak liczby podwójne, które działają jak liczby całkowite. Mają na przykład wartość max 2^53. Ale operatory bitowe traktują liczby tak, jakby były 32-bitowe, co jest dokładnie tym, czego chcesz w tym kodzie. Innymi słowy, ~~hash mówi "traktuj hash jako liczbę 32-bitową" w JavaScript. W szczególności odrzuca wszystkie ale dolne 32 bity (ponieważ operatory bitowe ~ patrzą tylko na dolne 32 bity), co jest identyczne z tym, jak działa przepełnienie Javy.

Jeśli tego nie posiadasz, kod hashowy obiektu będzie różny w zależności od tego, czy jest oceniany w Java-land czy w JavaScript land (poprzez kompilację 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-19 23:12:50