Javaで書き直されたJavaScript関数は異なる結果をもたらします


9

私がJavaで書き直そうとしているこのJavascript関数があります:

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

私のJava適応:

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

渡すと-1954896768、Javascriptバージョンが返され70528、Javaが返されます-896768。理由はわかりません。違いは、ifの条件内で開始しているようだ:Javascriptの機能であれば後にencodingRound2 = 2340070528、Javaでしばらく:encodingRound2 = -1954896768

オンラインで表示するためにこれらのreplを作成しました。

Javascripthttps : //repl.it/repls/NumbGuiltyHack

Javahttps : //repl.it/repls/ClumsyQualifiedProblem

編集:Java関数をこれに変更する

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

結果に影響を与えていないようです-それはまだです -896768


1
なぜJavaコードでにキャストencondindRound2するのintですか?これはとして定義されてlongいるため、より狭い型にキャストすると精度が失われる可能性があります。
ヨルダン

1
@Jordan-ifの内部-ビット単位の演算が実行されているため。JavaScriptは、64ビットの浮動小数点数として数値を格納しますが、ビット単位で実行すると、数値を32ビットの整数に変換します。以前は別のコードでこの問題がありました。Javaでビットごとに実行するとlong、オーバーフローのために異なる結果が得られました。
パーサー

削除(int)からキャストreturnのJava結果を変更しない行を、それが残っている-896768
parsecer

4
ああ、問題が見つかりました。を使用すると... + 0x80000000、Javaは値をintに変換します。これ0x80000000は、intリテラルと見なされるためです。その番号をに変更し0x80000000Lます。
ヨルダン

1
@ジョーダンうわー、あなたはウィザードです!動いた!回答を投稿してください。同意し​​ます
パーサー

回答:


9

Javaでは、0x80000000は32ビットintの範囲外であるため、ラップすると-2147483648になります。

JavaScriptでは、0x80000000は64ビットdoubleの範囲内にあるため、2147483648のままです。

明らかに、追加-2147483648と追加の2147483648結果は非常に大きな差異になります。

long必要(0x80000000|0)に応じて、Javaで0x80000000Lを使用するか、JS番号をで32ビット整数に強制変換できます。


2

これを試して。変換を行う際には、長い値を指定する必要があります。

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

        return  (encondindRound2 % 1_000_000);
    }

ただし、もう1つ注意すべき問題があります。Javascriptは%モジュロ演算子として扱い、Javaは単純な剰余演算子として扱います。この記事をチェックしてくださいここで詳細については。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.