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

Math.fround()

Methode

Rundet eine Zahl auf den nächstgelegenen Wert, der als 32-Bit-Gleitkommazahl mit einfacher Genauigkeit (IEEE 754 float) darstellbar ist.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Math.fround(x)

Beschreibung

Math.fround() ist eine statische Methode des Math-Objekts. JavaScript rechnet intern immer mit 64-Bit-Gleitkommazahlen (double precision). Math.fround() wandelt einen Wert in eine 32-Bit-Gleitkommazahl (single precision) um und gibt das Ergebnis wieder als normale JavaScript-Zahl (64 Bit) zurück. Dabei wird nach der Regel „round half to even“ gerundet.

Gebraucht wird die Methode vor allem, wenn Werte genau so vorliegen sollen, wie sie in einem Float32Array, in WebGL-Puffern, in WebAssembly (f32) oder in binären Dateiformaten gespeichert werden. Mit ihr kann man zum Beispiel prüfen, ob eine Zahl ohne Genauigkeitsverlust als float darstellbar ist, oder float-Arithmetik aus C/C++ nachbilden.

Werte, die für 32 Bit zu groß sind (Betrag ab etwa 3.4028235e38), werden zu Infinity bzw. -Infinity. Sehr kleine Werte können zu 0 bzw. -0 werden. NaN, ±0 und ±Infinity bleiben unverändert.

Parameter

Name Typ Default Beschreibung
$x Pflicht number Die umzuwandelnde Zahl. Andere Typen werden vorher wie bei Number(x) in eine Zahl umgewandelt. BigInt löst einen TypeError aus.

Rückgabewert

Typ
number
Beschreibung
Die nächstgelegene Zahl, die als 32-Bit-Gleitkommazahl darstellbar ist. Ist x nicht in eine Zahl umwandelbar, ist das Ergebnis NaN.

Beispiele

Genauigkeitsverlust sichtbar machen

console.log(Math.fround(5.5));   // exakt darstellbar
console.log(Math.fround(5.05));  // nicht exakt darstellbar
console.log(Math.fround(0.1));
console.log(Math.fround(2 ** 128)); // zu groß für float32
console.log(Math.fround(NaN));
5.5 5.050000190734863 0.10000000149011612 Infinity NaN

Prüfen, ob ein Wert verlustfrei als float32 gespeichert werden kann

const isExactFloat32 = (value) => Math.fround(value) === value;

console.log(isExactFloat32(0.5));     // true
console.log(isExactFloat32(0.1));     // false
console.log(isExactFloat32(16777216)); // 2^24 → true
console.log(isExactFloat32(16777217)); // 2^24 + 1 → false
true false true false

Vergleich mit Werten aus einem Float32Array

const vertices = new Float32Array([0.1, 0.2, 0.3]);

// Direkter Vergleich scheitert, weil die Werte als float32 gespeichert sind
console.log(vertices[0] === 0.1);              // false
// Mit Math.fround passt der Vergleich
console.log(vertices[0] === Math.fround(0.1)); // true
false true

float32-Arithmetik nachbilden (z. B. wie in C oder WebAssembly)

const f32Add = (a, b) => Math.fround(Math.fround(a) + Math.fround(b));

console.log(0.1 + 0.2);          // double-Rechnung
console.log(f32Add(0.1, 0.2));   // float-Rechnung
0.30000000000000004 0.30000001192092896

// Wichtig · Fallstricke

  • Das Ergebnis ist trotzdem ein 64-Bit-Wert: Zurückgegeben wird eine normale JavaScript-Zahl, deren Wert als float32 darstellbar ist. Wer mit mehreren Schritten float-genau rechnen will, muss jedes Zwischenergebnis erneut durch Math.fround() schicken.
  • Kein Leistungsgewinn: Anders als in asm.js früher manchmal angenommen, wird normaler Code durch Math.fround() nicht schneller. Die Methode dient der Genauigkeit und Kompatibilität, nicht der Optimierung.
  • Ganze Zahlen: Ganze Zahlen sind nur bis 224 (16.777.216) exakt als float32 darstellbar. Darüber hinaus gehen Stellen verloren.
  • Überlauf und Unterlauf: Werte mit einem Betrag über etwa 3.4028235e38 werden zu ±Infinity, sehr kleine Werte zu ±0.
  • BigInt: Math.fround(1n) löst einen TypeError aus.
  • Kompatibilität: In allen modernen Browsern und in Node.js verfügbar, nicht im Internet Explorer. Ein Polyfill ist leicht umzusetzen: (x) => new Float32Array([x])[0].