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

DataView.prototype.setFloat64()

Methode

Schreibt eine Zahl als 64-Bit-Gleitkommazahl (IEEE 754, doppelte Genauigkeit) in 8 Bytes ab dem angegebenen Byte-Offset des <code>DataView</code>.

seit JavaScript ES2015 (Baseline: alle Browser, Node.js 0.10+) Kategorie: method-property

Signatur

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

Beschreibung

setFloat64() wandelt den übergebenen Wert in eine Zahl um und legt ihn als IEEE-754-Gleitkommazahl mit doppelter Genauigkeit (double) in den 8 Bytes ab byteOffset ab. Da JavaScript-Zahlen intern schon als 64-Bit-Doubles gespeichert werden, geht dabei keine Genauigkeit verloren. Das ist der Unterschied zu setFloat32(), das auf einfache Genauigkeit rundet.

Man braucht die Methode immer dann, wenn Binärformate mit genauer Byte-Anordnung erzeugt werden sollen: Netzwerkprotokolle, Dateiformate (z. B. GeoJSON-Binärvarianten, WKB, Audio-Metadaten), der Datenaustausch mit WebAssembly-Speicher oder Nachrichten über WebSocket mit ArrayBuffer-Nutzlast.

Anders als bei einem Float64Array muss der Offset nicht auf 8 Bytes ausgerichtet sein, und die Byte-Reihenfolge lässt sich festlegen. Ohne Angabe schreibt DataView immer Big-Endian, egal welche Byte-Reihenfolge die Plattform hat. Für Little-Endian gibt man als drittes Argument true an.

Parameter

Name Typ Default Beschreibung
$byteOffset Pflicht number Offset in Bytes vom Anfang der Ansicht, ab dem geschrieben wird. Wird in eine Ganzzahl umgewandelt. Ab hier müssen noch mindestens 8 Bytes frei sein.
$value Pflicht number Der zu speichernde Wert. Nicht-Zahlen werden mit ToNumber umgewandelt (z. B. "3.5" → 3.5, undefined → NaN). Ein BigInt löst einen TypeError aus.
$littleEndian boolean false Mit true wird im Little-Endian-Format geschrieben, mit false bzw. ohne Angabe im Big-Endian-Format.

Rückgabewert

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

Beispiele

Grundlagen: Double schreiben und zurücklesen

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

view.setFloat64(0, Math.PI);
console.log(view.getFloat64(0));

// Bytes in Big-Endian-Reihenfolge anzeigen
const hex = [...new Uint8Array(buffer)]
  .map((b) => b.toString(16).padStart(2, '0'))
  .join(' ');
console.log(hex);
3.141592653589793 40 09 21 fb 54 44 2d 18

Byte-Reihenfolge: Big- vs. Little-Endian

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

view.setFloat64(0, 1.5);        // Big-Endian (Standard)
view.setFloat64(8, 1.5, true);  // Little-Endian

const bytes = new Uint8Array(view.buffer);
console.log(bytes.slice(0, 8).join(','));
console.log(bytes.slice(8).join(','));

// Falsche Reihenfolge beim Lesen ergibt Unsinn
console.log(view.getFloat64(8));       // als Big-Endian gelesen
console.log(view.getFloat64(8, true)); // korrekt
63,248,0,0,0,0,0,0 0,0,0,0,0,0,248,63 3.03865e-319 1.5

Praxis: GPS-Messpunkt als Binärpaket kodieren

// Format: [uint32 Zeitstempel (s)] [float64 Breite] [float64 Länge] – Little-Endian
const encodePoint = ({ time, lat, lon }) => {
  const view = new DataView(new ArrayBuffer(4 + 8 + 8));
  view.setUint32(0, time, true);
  view.setFloat64(4, lat, true);  // Offset 4: nicht 8-Byte-ausgerichtet, für DataView kein Problem
  view.setFloat64(12, lon, true);
  return view.buffer;
};

const decodePoint = (buffer) => {
  const view = new DataView(buffer);
  return {
    time: view.getUint32(0, true),
    lat: view.getFloat64(4, true),
    lon: view.getFloat64(12, true),
  };
};

const packet = encodePoint({ time: 1700000000, lat: 52.520008, lon: 13.404954 });
console.log(packet.byteLength);
console.log(decodePoint(packet));
// z. B. socket.send(packet);
20 { time: 1700000000, lat: 52.520008, lon: 13.404954 }

Fehlerfall: zu wenig Platz im Puffer

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

try {
  view.setFloat64(4, 42); // bräuchte die Bytes 4–11, es gibt aber nur 0–9
} catch (err) {
  console.log(err.name, '-', err.message);
}
RangeError - Offset is outside the bounds of the DataView

// Wichtig · Fallstricke

  • Standard ist Big-Endian: Ohne drittes Argument wird Big-Endian geschrieben. Die meisten x86- und ARM-Systeme sowie WebAssembly arbeiten dagegen mit Little-Endian. Wer littleEndian vergisst, erzeugt Daten, die ein Float64Array oder nativer Code falsch liest. Beim Schreiben und Lesen immer dieselbe Byte-Reihenfolge verwenden.
  • RangeError: Ist byteOffset negativ oder gilt byteOffset + 8 > view.byteLength, wird ein RangeError ausgelöst. Der Offset bezieht sich auf den Anfang der Ansicht, nicht auf den Anfang des Puffers.
  • TypeError: Die Methode wirft einen TypeError, wenn value ein BigInt ist oder der ArrayBuffer abgetrennt (detached) wurde, etwa nach einer Übertragung per postMessage oder nach transfer().
  • Sonderwerte: NaN, Infinity und -0 werden korrekt gespeichert. Das genaue Bitmuster von NaN kann sich je nach Engine unterscheiden, darauf sollte man sich nicht verlassen.
  • Leistung: Bei großen Mengen gleichartiger, ausgerichteter Werte in der nativen Byte-Reihenfolge ist ein Float64Array meist schneller. DataView spielt seine Stärken bei gemischten Strukturen und festgelegter Byte-Reihenfolge aus.
  • Kompatibilität: wird seit Jahren von allen modernen Browsern und von Node.js unterstützt. Funktioniert auch mit SharedArrayBuffer, ist dort aber nicht atomar.