Signatur
Beschreibung
Math.f16round() ist eine statische Methode des Math-Objekts. Sie wandelt eine Zahl in das Format IEEE 754 binary16 um und dann wieder zurück in eine normale JavaScript-Zahl (64-Bit-Double). Das Ergebnis ist der Wert, der tatsächlich übrig bleibt, wenn man die Zahl mit halber Genauigkeit speichert. Dieses Format hat 1 Vorzeichenbit, 5 Exponentenbits und 10 Mantissenbits. Das entspricht etwa 3 Dezimalstellen Genauigkeit, und der größte endliche Betrag ist 65504.
Sinnvoll ist die Methode überall, wo Daten als Float16 gespeichert oder übertragen werden: in WebGL/WebGPU (Texturen und Vertex-Puffer im Format half-float), bei Gewichten von Machine-Learning-Modellen, in Binärformaten wie glTF, OpenEXR oder CBOR und zusammen mit Float16Array oder DataView.prototype.setFloat16(). So lässt sich schon vor dem Schreiben prüfen, welcher Wert tatsächlich ankommt. Außerdem kann man damit Rundungsfehler gezielt nachbilden.
Gerundet wird nach der Standardregel von IEEE 754, round half to even: Liegt ein Wert genau in der Mitte zwischen zwei darstellbaren Werten, gewinnt der mit gerader Mantisse. Werte, deren Betrag zu groß ist, werden zu ±Infinity. Sehr kleine Werte werden zu subnormalen Zahlen oder zu ±0. NaN, ±Infinity und ±0 bleiben unverändert.
Die Methode ist das Gegenstück zu Math.fround() mit 32 Bit, verliert aber deutlich mehr Genauigkeit. Schon ganze Zahlen über 2048 sind nicht mehr alle exakt darstellbar.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $x Pflicht | number | Die Zahl, die gerundet werden soll. Andere Typen werden wie bei Number(x) in eine Zahl umgewandelt. Fehlt das Argument, ergibt sich NaN. |
Rückgabewert
Infinity bzw. -Infinity, wenn der Betrag zu groß ist (ab 65520), und NaN, wenn sich die Eingabe nicht in eine Zahl umwandeln lässt.Beispiele
Grundlegende Rundung
console.log(Math.f16round(5)); // exakt darstellbar
console.log(Math.f16round(5.5)); // exakt darstellbar
console.log(Math.f16round(5.05)); // nicht exakt darstellbar
console.log(Math.f16round(0.1));
console.log(Math.f16round(-1.337));
Grenzfälle: Überlauf, Unterlauf und Sonderwerte
console.log(Math.f16round(65504)); // größter endlicher Float16-Wert
console.log(Math.f16round(65519)); // wird noch zu 65504 abgerundet
console.log(Math.f16round(65520)); // Überlauf → Infinity
console.log(Math.f16round(2049)); // ganze Zahlen > 2048 nur in 2er-Schritten
console.log(Math.f16round(1e-8)); // kleiner als halber kleinster Subnormalwert → 0
console.log(Math.f16round(NaN), Math.f16round(-0));
console.log(Math.f16round('3.14')); // String wird umgewandelt
Vor dem Schreiben in einen Float16-Puffer auf Genauigkeitsverlust prüfen
// Prüft, ob sich ein Wert ohne Verlust als Float16 speichern lässt
const isExactFloat16 = (value) => Math.f16round(value) === value;
const weights = [0.5, 0.25, 0.1, 1024, 3000.7];
const report = weights.map((w) => ({
original: w,
gespeichert: Math.f16round(w),
exakt: isExactFloat16(w),
fehler: Math.abs(w - Math.f16round(w))
}));
console.table(report);
// Gleiches Ergebnis wie ein Float16Array (sofern unterstützt)
if (typeof Float16Array !== 'undefined') {
const buffer = new Float16Array(weights);
console.log(buffer.every((v, i) => v === Math.f16round(weights[i])));
}
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Methode ist relativ neu (ES2025) und fehlt in älteren Browsern und in Node.js-Versionen vor 24. Vor dem Aufruf mit
typeof Math.f16round === 'function'prüfen oder ein Polyfill einsetzen, etwa auscore-js. - Geringe Genauigkeit: Float16 bietet nur rund 3 signifikante Dezimalstellen. Für Geldbeträge, Zähler oder IDs ist das Format ungeeignet. Ganze Zahlen sind nur bis
2048lückenlos darstellbar. - Kleiner Wertebereich: Ab einem Betrag von
65520ist das Ergebnis±Infinity. Werte unter etwa2.98e-8werden zu0. Vor der Konvertierung skalieren oder begrenzen, zum Beispiel mitMath.min()undMath.max(). - Kein Speichergewinn: Das Ergebnis bleibt eine 64-Bit-JavaScript-Zahl. Tatsächlich Speicher spart man erst mit
Float16ArrayoderDataView.prototype.setFloat16(). - Nicht mit
Math.round()verwechseln:f16roundrundet auf das Float16-Raster, nicht auf ganze Zahlen. - Das Vorzeichen bleibt erhalten:
Math.f16round(-0)ergibt-0, und kleine negative Werte können ebenfalls zu-0werden.