Start · Sprachen · JavaScript · Referenz · Math.f16round()

Math.f16round()

Methode

Rundet eine Zahl auf den nächstgelegenen Wert, der sich als 16-Bit-Gleitkommazahl mit halber Genauigkeit (IEEE 754 binary16) darstellen lässt.

seit JavaScript ES2025 (Chrome/Edge 135+, Firefox 129+, Safari 18. Kategorie: method-property

Signatur

Math.f16round(x)

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

Typ
number
Beschreibung
Der nächstgelegene Wert, der als 16-Bit-Gleitkommazahl darstellbar ist, als normale JavaScript-Zahl. Ergibt 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));
5 5.5 5.05078125 0.0999755859375 -1.3369140625

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
65504 65504 Infinity 2048 0 NaN -0 3.140625

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])));
}
Tabelle: 0.5, 0.25 und 1024 exakt; 0.1 → 0.0999755859375; 3000.7 → 3000 true

// 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 aus core-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 2048 lückenlos darstellbar.
  • Kleiner Wertebereich: Ab einem Betrag von 65520 ist das Ergebnis ±Infinity. Werte unter etwa 2.98e-8 werden zu 0. Vor der Konvertierung skalieren oder begrenzen, zum Beispiel mit Math.min() und Math.max().
  • Kein Speichergewinn: Das Ergebnis bleibt eine 64-Bit-JavaScript-Zahl. Tatsächlich Speicher spart man erst mit Float16Array oder DataView.prototype.setFloat16().
  • Nicht mit Math.round() verwechseln: f16round rundet 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 -0 werden.