Frage

Ich arbeite an einer Seite, die IP -Adressinformationen verarbeitet, aber es wird über die Tatsache erstickt, dass Ganzzahlen signiert sind. Ich verwende Bitgewise -Operatoren, um es zu beschleunigen, aber das 64. Bit (signiert/vorzeichenlos) durcheinander.

Gibt es eine Möglichkeit, eine Zahl zu zwingen, in JavaScript nicht signiert zu werden? Es scheint gut zu funktionieren, bis das Subnetz größer als 30 oder weniger als 2 ist.

Versuche dies:

<html>
<body>

<script type='text/javascript'>
document.write( (1 << 30) +"<br/>");
document.write( (1 << 31) +"<br/>");
document.write( (1 << 32) +"<br/>");
</script>

</body>
</html>

Ergebnis:

1073741824 -2147483648 1

War es hilfreich?

Lösung

document.write( (1 << 31) +"<br/>");

Das << Der Bediener ist definiert als die Arbeit an signierten 32-Bit-Ganzzahlen (konvertiert aus der nativen Zahlspeicherung des Doppelprezisionsfloats). So 1<<31 muss zu einer negativen Zahl führen.

Der einzige JavaScript-Operator, der mit nicht signierten 32-Bit-Ganzzahlen arbeitet, ist >>>. Sie können dies ausnutzen, um einen unterschriebenen Eintritt in die Nummer zu konvertieren, an dem Sie mit den anderen Bitgewise-Betreibern in einen unvorstellbaren Eintritt in die Number gearbeitet haben:

document.write(( (1<<31)>>>0 )+'<br />');

In der Zwischenzeit:

document.write( (1 << 32) +"<br/>");

funktioniert nicht, da alle Verschiebungsvorgänge nur die niedrigsten 5-Bit-Verschiebungspunkte verwenden (auch in JavaScript und anderen C-ähnlichen Sprachen). <<32 ist gleich <<0, dh. Keine Änderung.

Andere Tipps

Verwenden Sie >>> anstelle von >>, um eine nicht signierte rechte Verschiebung anstelle einer signaler Verlängerung zu erhalten. Alle anderen Bitgewise -Operatoren verhalten sich genauso, unabhängig davon, ob INTs signiert sind oder nicht.

Ihr Code, das "Wenn Subnetz ... weniger als 2 ist" ist, ist besorgniserregend. Das hört sich so an, als hätten Sie einen Fehler, der nichts mit der Unterzeichnung von Ganzzahlen zusammenhängt.

Douglas Crockford glaubt, dass Bitwise -Operatoren einer der schlechten Teile von JavaScript ist:

In Java arbeiten die bitimen Betreiber mit Ganzzahlen. JavaScript hat keine Ganzzahlen. Es hat nur doppelte Präzisionsschwimmpunktzahlen. Die Bitgewise -Betreiber konvertieren also ihre Anzahl der Operanden in Ganzzahlen, machen ihr Geschäft und konvertieren sie dann zurück. In den meisten Sprachen stehen diese Betreiber sehr nahe an der Hardware und sehr schnell. In JavaScript sind sie sehr weit von der Hardware entfernt und sehr langsam. JavaScript wird selten zur Bitmanipulation verwendet.

- Douglas Crockford in "JavaScript: The Good Parts", Anhang B, Bitwise-Operatoren (Hervorhebung hinzugefügt)

Sind Sie sicher, dass bitweise Operatoren Ihre Logik wirklich beschleunigen?

JavaScript hat keine Ganzzahlen, alle Zahlen sind tatsächlich Doppel.

Das JavaScript 1.5 Referenz von Mozilla schlägt vor, dass man nur bitweise Operationen für 32-Bit-Zahlen sicher verwenden kann.

Hier sind zwei Funktionen, die IPv4 -Adressen in/von unsignierten Ganzzahlen in JavaScript konvertieren:

function ip2long(ip) {
    var ipl=0;
    ip.split('.').forEach(function( octet ) {
        ipl<<=8;
        ipl+=parseInt(octet);
    });
    return(ipl >>>0);
}

function long2ip (ipl) {
    return ( (ipl>>>24) +'.' +
        (ipl>>16 & 255) +'.' +
        (ipl>>8 & 255) +'.' +
        (ipl & 255) );
}

Welche Art von IP -Adressen haben Sie? IPv4 verwendet nur 32 -Bit -Adressen 52 -Bit -Ganzzahl Teil). IPv6 verwendet 128 -Bit -Adressen, sodass Sie ein Array verwenden müssen. Ich vermute, dass etwas anderes kaputt ist.

Bearbeiten] Erstellen Sie eine kleine Bibliothek, die ein Array von zwei INTs als interner Datentyp verwendet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top