Start · Sprachen · JavaScript · Referenz · DataView.prototype.setBigInt64()

DataView.prototype.setBigInt64()

Methode

Schreibt einen <code>BigInt</code> als vorzeichenbehaftete 64-Bit-Ganzzahl in 8 Bytes ab dem angegebenen Byte-Offset der <code>DataView</code>.

seit JavaScript ES2020 (Baseline: alle modernen Browser, Node.js 1 Kategorie: method-property

Signatur

DataView.prototype.setBigInt64(byteOffset, value, littleEndian)

Beschreibung

Die Methode setBigInt64() schreibt einen BigInt-Wert als 64-Bit-Ganzzahl mit Vorzeichen (Zweierkomplement) in den zugrunde liegenden ArrayBuffer einer DataView. Belegt werden genau 8 Bytes ab byteOffset. Der Offset muss nicht ausgerichtet sein, er kann also auf ein beliebiges Byte zeigen.

Gebraucht wird sie vor allem, wenn man mit Binärformaten und Protokollen arbeitet, die 64-Bit-Ganzzahlen enthalten, etwa Zeitstempel in Nanosekunden, Datenbank-IDs, Dateiköpfe, WebSocket- oder WebTransport-Nachrichten und WebAssembly-Speicher. Ein normaler Number-Wert hält Ganzzahlen nur bis 253 − 1 exakt. Mit BigInt lässt sich dagegen der volle Bereich von −263 bis 263 − 1 verlustfrei speichern.

Anders als bei typisierten Arrays wie BigInt64Array legt man die Byte-Reihenfolge bei jedem Aufruf selbst fest. Ohne Angabe gilt Big-Endian. Mit littleEndian = true wird in Little-Endian geschrieben, der Reihenfolge der meisten heutigen CPUs und vieler Dateiformate.

Werte außerhalb des 64-Bit-Bereichs werden modulo 264 abgeschnitten, genau wie bei BigInt.asIntN(64, value). Einen Fehler gibt es dabei nicht.

Parameter

Name Typ Default Beschreibung
$byteOffset Pflicht number Position in Bytes ab dem Anfang der View, an der geschrieben wird. Wird in eine Ganzzahl umgewandelt. byteOffset + 8 darf byteLength nicht überschreiten.
$value Pflicht bigint Der zu speichernde Wert. Er muss ein BigInt sein oder sich in einen umwandeln lassen (z. B. true oder "42"). Ein Number-Wert löst einen TypeError aus. Werte außerhalb des 64-Bit-Bereichs werden abgeschnitten.
$littleEndian boolean false Mit true wird in Little-Endian geschrieben. Mit false oder ohne Angabe in Big-Endian (Netzwerk-Byte-Reihenfolge).

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Die Methode ändert den zugrunde liegenden Puffer direkt.

Beispiele

Grundlegende Nutzung: Schreiben und Zurücklesen

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);

// Größte vorzeichenbehaftete 64-Bit-Zahl ab Byte 0 schreiben
view.setBigInt64(0, 9223372036854775807n);
// Negativen Wert ab Byte 8 schreiben
view.setBigInt64(8, -42n);

console.log(view.getBigInt64(0));
console.log(view.getBigInt64(8));
9223372036854775807n -42n

Byte-Reihenfolge: Big-Endian und Little-Endian im Vergleich

const view = new DataView(new ArrayBuffer(8));
const hex = () => [...new Uint8Array(view.buffer)]
  .map((b) => b.toString(16).padStart(2, '0'))
  .join(' ');

view.setBigInt64(0, 0x0102030405060708n); // Big-Endian (Standard)
console.log(hex());

view.setBigInt64(0, 0x0102030405060708n, true); // Little-Endian
console.log(hex());
01 02 03 04 05 06 07 08 08 07 06 05 04 03 02 01

Praxis: Binären Nachrichtenkopf mit Nanosekunden-Zeitstempel aufbauen

// Aufbau: [Typ: 1 Byte][Zeitstempel: 8 Bytes, LE][Nutzlastlänge: 4 Bytes, LE]
const buildHeader = (type, timestampNs, payloadLength) => {
  const view = new DataView(new ArrayBuffer(13));
  view.setUint8(0, type);
  view.setBigInt64(1, timestampNs, true); // nicht ausgerichteter Offset ist erlaubt
  view.setUint32(9, payloadLength, true);
  return view.buffer;
};

const nowNs = BigInt(Date.now()) * 1_000_000n;
const header = buildHeader(0x01, nowNs, 256);

const check = new DataView(header);
console.log(check.getBigInt64(1, true) === nowNs);
console.log(header.byteLength);
true 13

Fehlerfälle: Number statt BigInt und Offset außerhalb des Puffers

const view = new DataView(new ArrayBuffer(8));

try {
  view.setBigInt64(0, 42); // Number statt BigInt
} catch (err) {
  console.log(err.name);
}

try {
  view.setBigInt64(1, 42n); // 1 + 8 > 8 Bytes
} catch (err) {
  console.log(err.name);
}

// Überlauf wird stillschweigend abgeschnitten
view.setBigInt64(0, 2n ** 63n);
console.log(view.getBigInt64(0));
TypeError RangeError -9223372036854775808n

// Wichtig · Fallstricke

  • Nur BigInt: Ein Number wie 42 löst einen TypeError aus. Deshalb 42n oder BigInt(42) verwenden. Achtung: BigInt(1.5) wirft einen RangeError, weil nur ganze Zahlen umgewandelt werden.
  • Standard ist Big-Endian: Wer den dritten Parameter weglässt, schreibt in Big-Endian. Formate wie WebAssembly-Speicher oder viele Dateiformate erwarten aber Little-Endian. Das ist eine häufige Fehlerquelle, wenn Daten mit BigInt64Array ausgetauscht werden, denn das nutzt die Byte-Reihenfolge der Plattform (meist Little-Endian).
  • Stilles Abschneiden: Werte außerhalb von −263 bis 263 − 1 werden ohne Fehler modulo 264 umgebrochen. Wenn nötig, den Bereich vorher prüfen, z. B. mit BigInt.asIntN(64, v) === v.
  • RangeError: Ein RangeError tritt auf, wenn byteOffset negativ ist oder byteOffset + 8 größer als byteLength der View ist. Einen TypeError gibt es, wenn der Puffer abgekoppelt (detached) ist, etwa nach einer Übertragung per postMessage, oder wenn er unveränderlich ist.
  • Kompatibilität: Die Methode ist seit ES2020 verfügbar (Chrome 67, Firefox 68, Safari 15, Node.js 10.4). In älteren Umgebungen fehlt sie, zusammen mit BigInt selbst. Einen einfachen Polyfill gibt es nicht: Man muss den Wert auf zwei 32-Bit-Hälften mit setUint32 aufteilen.