Java'da double tilde (~~) 'in anlamı nedir?


192

Guava'nın kaynak koduna göz atarken, aşağıdaki kod parçasına rastladım ( hashCodeiç sınıf için uygulamanın bir parçası 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;

Her ikisi de adjustve hasholan intlar. Ben Java hakkında bildiklerimizi itibaren ~olumsuzlama bit düzeyinde yollarla, yani adjust = ~~adjustve hash = ~~hashdeğişmeden değişkenleri bırakmalısınız. Küçük testi çalıştırmak (elbette iddialar etkinken),

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

bunu doğrular. Guava'lıların ne yaptığını bildiklerini varsayarsak, bunu yapmaları için bir sebep olmalı. Soru ne?

DÜZENLEME Yorumlarda belirtildiği gibi, yukarıdaki test ieşittir Integer.MAX_VALUE. Yana i <= Integer.MAX_VALUEhep doğrudur, sonsuza döngü önlemek için döngü dışında çantayı kontrol etmek gerekir. Ancak, çizgi

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

derleyici uyarısı verir "özdeş ifadeleri karşılaştırmak", hemen hemen çivi.


42
@dr_andonuts Guava, bugünlerde bir projeye dahil edilecek oldukça standart bir kütüphane.
yshavit

4
Onaylayıcı kenar kasasını kontrol etmez Integer.MAX_VALUE. İle kontrast -(-Integer.MIN_VALUE) != Integer.MIN_VALUE.
Franky

3
@Franky Maaartinus ne dedi. -Integer.MIN_VALUEetrafına sarar Integer.MIN_VALUE, böylece tekrar tekrar basitçe üretir Integer.MIN_VALUE.

2
@maaartinus, @hvd, belirttiğiniz için teşekkürler. Şimdi bunu hatırlıyorum -x = (~x) + 1.
Franky

7
@dr_andonuts Trolling mi yapıyorsunuz? Neden anlamadığınız şeylerden kaçıyorsunuz. StackOverflow bunun için buradadır: öğrenmenize yardımcı olmak için.
Jared Burrows

Yanıtlar:


245

Java'da hiçbir şey ifade etmez.

Ancak bu yorum, satırın özellikle Java'yı JavaScript'e derlemenin bir yolu olan GWT için olduğunu söylüyor.

JavaScript'te, tamsayılar tamsayı gibi davranan iki katına benzer. Örneğin, maksimum 2 ^ 53 değerine sahiptirler. Ancak bitsel operatörler sayıları 32 bitmiş gibi ele alırlar, bu da tam olarak bu kodda istediğiniz gibi. Başka bir deyişle, JavaScript'te "32 bit sayı gibi ~~hashdavran" diyor hash. Özellikle, alt 32 bit dışındaki her şeyi atar (bitsel ~işleçler yalnızca alt 32 bite baktığından), bu da Java'nın taşmasının nasıl çalıştığı ile aynıdır.

Buna sahip değilseniz, nesnenin karma kodu, Java arazisinde mi yoksa JavaScript arazisinde mi (GWT derlemesi aracılığıyla) değerlendirilmesine bağlı olarak farklı olacaktır.


10
@harold Bu bir GWT şey değil, JavaScript bir şey. Bu sadece sayılar o dilde çalışıyor.
yshavit

18
@yshavit Ancak, öyle değil sayılar Java nasıl çalıştığını. GWT, sayıların JS ve JVM'de kullanıcıdan farklı uygulandığı gerçeğini gizlemezse, gerçekten de zayıf bir derleyicidir.
valderman

8
@harold, evet, tamsayıları yanlış uygulayan JavaScript (aslında JavaScript'te tamsayı türü diye bir şey yoktur).
MikeTheLiar

8
@valderman Bu iyi bir nokta. Ekleme |0ya ~~ben performans isabet (her ifadenin her adımda eklemek zorundayız) ne olacağını bilmiyorum ama böyle sesler, zor olmazdı. Tasarımla ilgili düşüncelerin ne olduğunu bilmiyorum. Fwiw, tutarsızlık GWT'nin uyumluluk sayfasında belgelenmiştir .
yshavit

6
hashCodekasıtlı olarak taşma ihtimalini mahkemelere hatta beklemektedir. Tutarsızlığı gözlemleyebileceğiniz tek yer, çoğu kodda ortaya çıkan bir sorun olmayan normal bir Java int'in nereye taşacağıdır; sadece bu garip davada geçerli.
Louis Wasserman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.