Baseline Widely available
Die statische Dateneigenschaft Number.EPSILON
repräsentiert die Differenz zwischen 1 und der kleinsten Gleitkommazahl gröÃer als 1.
const result = Math.abs(0.2 - 0.3 + 0.1);
console.log(result);
// Expected output: 2.7755575615628914e-17
console.log(result < Number.EPSILON);
// Expected output: true
Wert
2-52 oder ungefähr 2.2204460492503130808472633361816E-16
.
Number.EPSILON
ist die Differenz zwischen 1 und der nächsten gröÃeren Zahl, die im Number-Format darstellbar ist, da das double precision floating point format nur 52 Bits zur Darstellung der Mantisse hat, und das niedrigste Bit eine Bedeutung von 2-52 hat.
Beachten Sie, dass die absolute Genauigkeit von Gleitkommazahlen abnimmt, je gröÃer die Zahl wird, da der Exponent wächst, während die Genauigkeit der Mantisse gleich bleibt. Number.MIN_VALUE
ist die kleinste darstellbare positive Zahl, die viel kleiner ist als Number.EPSILON
.
Da EPSILON
eine statische Eigenschaft von Number
ist, wird es immer als Number.EPSILON
verwendet, anstatt als Eigenschaft eines Zahlenwertes.
Jedes Zahlencodierungssystem, das eine endliche Anzahl von Bits belegt, unabhängig von der gewählten Basis (z.B. dezimal oder binär), wird notwendigerweise nicht in der Lage sein, alle Zahlen genau darzustellen, da Sie versuchen, eine unendliche Anzahl von Punkten auf der Zahlenlinie mit einer endlichen Menge von Speicher darzustellen. Zum Beispiel kann ein dezimales (Basis-10) System nicht 1/3 genau darstellen, und ein binäres (Basis-2) System kann 0.1
nicht genau darstellen. Daher ist z.B. 0.1 + 0.2
nicht genau gleich 0.3
:
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false
Aus diesem Grund wird oft geraten, Gleitkommazahlen niemals mit ===
zu vergleichen. Stattdessen können wir zwei Zahlen als gleich betrachten, wenn sie nahe genug beieinander liegen. Die Konstante Number.EPSILON
ist normalerweise ein vernünftiger Schwellenwert für Fehler, wenn die Arithmetik in der GröÃenordnung von 1
liegt, da EPSILON
im Wesentlichen angibt, wie genau die Zahl "1" ist.
function equal(x, y) {
return Math.abs(x - y) < Number.EPSILON;
}
const x = 0.2;
const y = 0.3;
const z = 0.1;
console.log(equal(x + z, y)); // true
Allerdings ist Number.EPSILON
ungeeignet für jegliche Arithmetik, die mit einer gröÃeren GröÃenordnung arbeitet. Wenn Ihre Daten in der GröÃenordnung von 103 liegen, wird der Dezimalteil eine viel geringere Genauigkeit als Number.EPSILON
haben:
function equal(x, y) {
return Math.abs(x - y) < Number.EPSILON;
}
const x = 1000.1;
const y = 1000.2;
const z = 2000.3;
console.log(x + y); // 2000.3000000000002; error of 10^-13 instead of 10^-16
console.log(equal(x + y, z)); // false
In diesem Fall ist eine gröÃere Toleranz erforderlich. Da die verglichenen Zahlen eine GröÃenordnung von ungefähr 2000
haben, schafft ein Multiplikator wie 2000 * Number.EPSILON
genügend Toleranz für diesen Fall.
function equal(x, y, tolerance = Number.EPSILON) {
return Math.abs(x - y) < tolerance;
}
const x = 1000.1;
const y = 1000.2;
const z = 2000.3;
console.log(equal(x + y, z, 2000 * Number.EPSILON)); // true
Neben der GröÃenordnung ist es wichtig, die Genauigkeit Ihrer Eingaben zu berücksichtigen. Wenn die Zahlen z.B. aus einer Formulareingabe gesammelt werden und der Eingabewert nur in Schritten von 0.1
(d.h. <input type="number" step="0.1">
) angepasst werden kann, macht es in der Regel Sinn, eine viel gröÃere Toleranz zuzulassen, wie 0.01
, da die Daten nur eine Genauigkeit von 0.1
haben.
Hinweis: Wichtige Erkenntnis: Verwenden Sie Number.EPSILON
nicht einfach als Schwellenwert für den Gleichheitstest. Verwenden Sie einen Schwellwert, der für die GröÃenordnung und Genauigkeit der Zahlen, die Sie vergleichen, geeignet ist.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4