Die in Java neu geschriebene Javascript-Funktion liefert unterschiedliche Ergebnisse


9

Es gibt diese Javascript-Funktion, die ich in Java neu schreiben möchte:

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

Meine Java-Anpassung:

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

Wenn ich bestanden habe -1954896768, kehrt die Javascript-Version zurück 70528, während Java zurückkehrt -896768. Ich bin mir nicht sicher warum. Der Unterschied scheint innerhalb der if-Bedingung zu beginnen: in der Javascript-Funktion nach dem ifencodingRound2 = 2340070528 , während in Java : encodingRound2 = -1954896768.

Ich habe diese Antworten gemacht, um es online zu zeigen:

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

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

BEARBEITEN : Ändern der Java-Funktion in diese

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

scheint das Ergebnis nicht zu beeinflussen - es ist immer noch -896768


1
Warum gießen Sie encondindRound2in einen intim Java-Code? Da es als definiert ist long, verlieren Sie möglicherweise an Präzision, wenn Sie es auf einen engeren Typ umwandeln.
— Jordanien

1
@ Jordan, weil - innerhalb des if - eine bitweise Operation ausgeführt wird. Obwohl Javascript Zahlen als 64-Bit-Floats speichert, konvertiert es bei bitweiser Ausführung Zahlen in 32-Bit-Ganzzahlen. Ich hatte dieses Problem mit einem anderen Code zuvor, als ich bitweise mit Java arbeitete long, was aufgrund des Überlaufs zu unterschiedlichen Ergebnissen führte.
— Parsecer

Das Entfernen der (int)Besetzung aus der returnZeile ändert nichts am Java-Ergebnis, es bleibt-896768
— Parsecer

4
Ah, ich habe das Problem gefunden. Wenn Sie fortfahren ... + 0x80000000, konvertiert Java den Wert in ein int, da 0x80000000dies als int-Literal betrachtet wird. Ändern Sie diese Nummer in 0x80000000L.
— Jordanien

1
@ Jordan Wow, du bist ein Zauberer! Es funktionierte! Bitte
— poste

Antworten:


9

In Java liegt 0x80000000 außerhalb des Bereichs eines 32-Bit-Int, sodass es sich um -2147483648 handelt.

In JavaScript liegt 0x80000000 deutlich im Bereich eines 64-Bit-Double, sodass es 2147483648 bleibt.

Offensichtlich führt das Hinzufügen -2147483648gegenüber dem Hinzufügen 2147483648zu einer sehr großen Diskrepanz.

Sie können entweder eine long0x80000000L in Java verwenden oder Ihre JS-Nummer in eine 32-Bit-Int mit zwingen (0x80000000|0), je nachdem, was Sie möchten.


2

Versuche dies. Bei der Konvertierung müssen Sie lange Werte angeben.

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

        return  (encondindRound2 % 1_000_000);
    }

Es gibt jedoch noch ein anderes Problem, dessen Sie sich bewusst sein sollten. Javascript wird %als Modulo-Operator behandelt, Java als einfacher Restoperator. Weitere Informationen finden Sie in diesem Beitrag hier .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.