Signatur
Beschreibung
Der Operator >>> (vorzeichenlose Rechtsverschiebung, auch „Zero-fill Right Shift“) wandelt den linken Operanden in eine 32-Bit-Ganzzahl ohne Vorzeichen um und verschiebt sein Bitmuster um y Stellen nach rechts. Bits, die rechts herausfallen, gehen verloren. Von links wird immer mit 0 aufgefüllt. Deshalb ist das Ergebnis immer eine nicht-negative Zahl im Bereich 0 bis 232 − 1.
Anders als >> (vorzeichenbehaftete Rechtsverschiebung) wird das Vorzeichenbit nicht kopiert. Bei positiven Zahlen liefern beide Operatoren dasselbe Ergebnis. Bei negativen Zahlen unterscheiden sie sich deutlich: -9 >> 2 ergibt -3, -9 >>> 2 dagegen 1073741821.
In der Praxis wird >>> vor allem so eingesetzt:
x >>> 0wandelt einen Wert in eine vorzeichenlose 32-Bit-Zahl um (entspricht der internen Operation ToUint32). Das ist üblich bei Hash-Funktionen, Prüfsummen und Polyfills.- Man liest einzelne Bytes aus gepackten 32-Bit-Werten aus, z. B. aus RGBA-Farben oder Netzwerkprotokollen, ohne dass das Vorzeichen stört.
- Man teilt schnell ganzzahlig durch Zweierpotenzen, z. B.
(lo + hi) >>> 1bei der binären Suche.
Der rechte Operand wird ebenfalls in eine 32-Bit-Ganzzahl umgewandelt. Davon zählen nur die unteren 5 Bits, also y & 31. Die zugehörige Zuweisung heißt x >>>= y.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $x Pflicht | number | any | Linker Operand, dessen Bits verschoben werden. Wird mit ToUint32 umgewandelt: Nachkommastellen werden abgeschnitten, NaN/Infinity werden zu 0, Bits oberhalb von Bit 31 fallen weg. BigInt ist nicht erlaubt. |
|
| $y Pflicht | number | any | Anzahl der Stellen, um die verschoben wird. Es zählen nur die unteren 5 Bits (y & 31), der wirksame Wert liegt also immer zwischen 0 und 31. |
Rückgabewert
0 und 4294967295 (232 − 1), also nach rechts verschobenes, vorzeichenloses 32-Bit-Muster von x.Beispiele
Grundlagen: >>> im Vergleich zu >>
console.log(9 >>> 2); // 00…1001 → 00…0010
console.log(9 >> 2);
// Bei negativen Zahlen unterscheiden sich die Operatoren
console.log(-9 >> 2); // Vorzeichen bleibt erhalten
console.log(-9 >>> 2); // links wird mit Nullen aufgefüllt
In vorzeichenlose 32-Bit-Zahl umwandeln und Bitmuster anzeigen
const toUint32 = (n) => n >>> 0;
console.log(toUint32(-1));
console.log(toUint32(2 ** 32 + 5)); // Bits oberhalb von Bit 31 fallen weg
console.log(toUint32(3.99)); // Nachkommastellen werden abgeschnitten
// Zweierkomplement einer negativen Zahl sichtbar machen
console.log((-5).toString(2));
console.log((-5 >>> 0).toString(2));
RGBA-Farbwert in einzelne Kanäle zerlegen
const rgba = 0xff8800cc; // R=255, G=136, B=0, A=204
const unpack = (c) => ({
r: c >>> 24, // mit >> käme hier -1 heraus!
g: (c >>> 16) & 0xff,
b: (c >>> 8) & 0xff,
a: c & 0xff,
});
console.log(unpack(rgba));
console.log(rgba >> 24); // falsch: Vorzeichenbit wird kopiert
32-Bit-Hash (FNV-1a) mit vorzeichenlosem Ergebnis
const fnv1a = (str) => {
let hash = 0x811c9dc5;
for (const ch of str) {
hash ^= ch.codePointAt(0);
hash = Math.imul(hash, 0x01000193);
}
return hash >>> 0; // immer positiv, 0 … 4294967295
};
const h = fnv1a('programmierung.net');
console.log(h >= 0, h.toString(16).padStart(8, '0'));
Mitte bei der binären Suche
const binarySearch = (arr, target) => {
let lo = 0;
let hi = arr.length - 1;
while (lo <= hi) {
const mid = (lo + hi) >>> 1; // ganzzahlige Division durch 2
if (arr[mid] === target) return mid;
if (arr[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
};
console.log(binarySearch([1, 3, 5, 7, 9, 11], 9));