Signatur
Beschreibung
getFloat16() liest zwei Bytes ab der angegebenen Position im zugrunde liegenden ArrayBuffer und interpretiert sie als Gleitkommazahl im Format IEEE 754 binary16 („half precision“): 1 Vorzeichenbit, 5 Exponentenbits, 10 Mantissenbits. Das Ergebnis wird exakt in eine normale JavaScript-number (64-Bit-Double) umgewandelt.
Gebraucht wird die Methode vor allem beim Einlesen binärer Formate, die aus Speicher- oder Bandbreitengründen Half-Floats verwenden, z. B. Vertex-Daten in glTF/WebGL/WebGPU, HDR-Bildformate wie OpenEXR, Gewichte von Machine-Learning-Modellen oder Sensordaten aus Netzwerkprotokollen.
Anders als bei einem Float16Array kannst du mit DataView an beliebigen, auch nicht ausgerichteten Byte-Positionen lesen und die Byte-Reihenfolge (Endianness) pro Aufruf festlegen. Standard ist Big-Endian. Die meisten Dateiformate und praktisch alle aktuellen CPUs nutzen aber Little-Endian, deshalb musst du dort meist true als zweites Argument übergeben.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $byteOffset Pflicht | number | Position in Bytes, ab der gelesen wird, gezählt ab dem Anfang der View (nicht des Buffers). Wird in eine ganze Zahl umgewandelt. | |
| $littleEndian | boolean | false | Bei true wird Little-Endian gelesen, bei false oder fehlendem Argument Big-Endian. |
Rückgabewert
number, auch Sonderwerte wie Infinity, -Infinity, NaN und -0. Endliche Beträge liegen zwischen etwa 6,0e-8 (kleinster subnormaler Wert) und 65504.Beispiele
Half-Float in Big- und Little-Endian lesen
const view = new DataView(new ArrayBuffer(2));
// Bytes 0x48 0x42 in den Speicher schreiben
view.setUint8(0, 0x48);
view.setUint8(1, 0x42);
console.log(view.getFloat16(0)); // Big-Endian: 0x4842
console.log(view.getFloat16(0, true)); // Little-Endian: 0x4248
Präzisionsverlust beim Umweg über Float16
const view = new DataView(new ArrayBuffer(2));
view.setFloat16(0, 0.1, true);
const gelesen = view.getFloat16(0, true);
console.log(gelesen);
console.log(gelesen === Math.f16round(0.1));
Vertex-Daten aus einem Binärblock parsen (Stride, nicht ausgerichtet)
// Jeder Vertex: 1 Byte Flags + 3 × float16 (x, y, z), also 7 Bytes, Little-Endian
const parseVertices = (buffer) => {
const view = new DataView(buffer);
const stride = 7;
const vertices = [];
for (let off = 0; off + stride <= view.byteLength; off += stride) {
vertices.push({
flags: view.getUint8(off),
x: view.getFloat16(off + 1, true),
y: view.getFloat16(off + 3, true),
z: view.getFloat16(off + 5, true),
});
}
return vertices;
};
// Testdaten erzeugen
const buf = new ArrayBuffer(14);
const w = new DataView(buf);
[[1, 1.5, -2, 0.25], [0, 65504, 0, -0.5]].forEach(([f, x, y, z], i) => {
const o = i * 7;
w.setUint8(o, f);
w.setFloat16(o + 1, x, true);
w.setFloat16(o + 3, y, true);
w.setFloat16(o + 5, z, true);
});
console.log(parseVertices(buf));
Feature-Erkennung und Bereichsfehler abfangen
const readHalf = (view, offset, le = true) => {
if (typeof DataView.prototype.getFloat16 !== 'function') {
throw new Error('getFloat16 wird in dieser Umgebung nicht unterstützt');
}
try {
return view.getFloat16(offset, le);
} catch (err) {
if (err instanceof RangeError) return undefined;
throw err;
}
};
const view = new DataView(new ArrayBuffer(3));
console.log(readHalf(view, 1)); // Bytes 1–2: gültig
console.log(readHalf(view, 2)); // bräuchte Byte 3: außerhalb
// Wichtig · Fallstricke
- Endianness: Standard ist Big-Endian. Wer
littleEndianweglässt, bekommt bei Little-Endian-Dateiformaten (glTF, EXR, die meisten ML-Formate) falsche Werte, ohne dass ein Fehler geworfen wird. - RangeError: Ein Fehler wird geworfen, wenn
byteOffsetnegativ ist oderbyteOffset + 2größer alsbyteLengthder View. EinTypeErrorkommt, wenn der Buffer abgetrennt (detached) ist, etwa nach einer Übertragung perpostMessage. - Genauigkeit: Float16 hat nur rund 3 signifikante Dezimalstellen und einen Maximalwert von 65504. Das Lesen selbst ist verlustfrei, beim Schreiben mit
setFloat16()wird aber gerundet.Math.f16round()liefert denselben gerundeten Wert. - Kompatibilität: Neu in ES2025 (Chrome/Edge 135, Firefox 129, Safari 18.2, Node.js 24). In älteren Umgebungen fehlt die Methode. Dann prüfst du per Feature-Erkennung und liest ersatzweise mit
getUint16()plus manueller Bit-Dekodierung oder nutzt ein Polyfill (z. B.core-js). - Leistung: Für große, ausgerichtete Blöcke mit der Byte-Reihenfolge der Plattform ist ein
Float16Arraymeist schneller als viele einzelnegetFloat16()-Aufrufe.