Java ile yeniden yazılan Javascript işlevi farklı sonuçlar verir


9

Java'da yeniden yazmaya çalıştığım bu Javascript işlevi var:

function normalizeHash(encondindRound2) {
    if (encondindRound2 < 0) {
        encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
    }
    return encondindRound2 % 1E6;
}

Java uyarlamam:

public long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 = (((int) encondindRound2) & 0x7fffffff) + 0x80000000;
        }
        return (((int) encondindRound2) % 1_000_000);
    }

Ben geçtikten sonra -1954896768, JavaScript versiyonu döner 70528Java getiriler ise -896768. Neden olduğundan emin değilim. Fark if koşulu içinde başlıyor gibi görünüyor: encodingRound2 = 2340070528Java , if ise Javascript işlevinden sonra encodingRound2 = -1954896768.

Çevrimiçi olarak göstermek için bu kopyaları yaptım:

Javascript : https://repl.it/repls/NumbGuiltyHack

Java : https://repl.it/repls/ClumsyQualifiedProblem

EDIT : Java işlevini bu şekilde değiştirme

public long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
        }
        return (encondindRound2 % 1_000_000);
    }

sonucu etkilemiyor gibi görünüyor - hala -896768


1
Neden döküm olan encondindRound2bir etmek intJava kodunda? Bir olarak tanımlandığından long, daha dar bir türe yayınlarsanız hassasiyeti kaybedersiniz.
Ürdün

1
@Jordan çünkü - if içinde - üzerinde bitsel bir işlem var. Javascript, sayıları 64 bit yüzer olarak saklasa da, bitsel yaparken sayıları 32 bit tamsayılara dönüştürür. Daha önce, Java ile bitsel yaparken longtaşma nedeniyle farklı sonuçlar verdi kod başka bir parça ile bu sorunu vardı .
parsecer

Çıkarma (int)gelen döküm returnJava sonucunu değiştirmez hattı, bu kalır-896768
parsecer

4
Ah, sorunu buldum. Yapıştırdığınızda ... + 0x80000000, Java değeri int değerine dönüştürür, çünkü 0x80000000int değişmezidir. Bu sayıyı olarak değiştirin 0x80000000L.
Ürdün

1
@Jordan Wow, sen büyücüsün! İşe yaradı! Lütfen cevabınızı gönderin ve kabul edeceğim
parsecer

Yanıtlar:


9

Java'da 0x80000000, 32bit int aralığının dışındadır, bu nedenle -2147483648'e sarılır.

JavaScript'te 0x80000000, 64 bitlik bir çift aralığın içindedir, bu nedenle 2147483648 olarak kalır.

Açıkçası, ekleme -2147483648ve ekleme 2147483648sonuçları çok büyük bir tutarsızlık içinde.

longJava'da bir 0x80000000L kullanabilir veya JS numaranızı (0x80000000|0), istediğiniz yere bağlı olarak 32bit int'e zorlayabilirsiniz .


2

Bunu dene. Dönüşüm yaparken uzun değerler belirtmeniz gerekir.

    public static long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 =  (encondindRound2 & 0x7fffffffL) + 0x80000000L;
        }

        return  (encondindRound2 % 1_000_000);
    }

Ancak bilmeniz gereken başka bir sorun daha var. Javascript, %Java'nın basit bir kalan işleç olarak davrandığı bir modulo operatörü gibi davranır. Bu yazıyı göz atın burada daha fazla bilgi için.

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.