Wenn Sie in Java mit Gleitkommazahlen arbeiten, stellen Sie möglicherweise fest, dass „Double“ manchmal zu unerwarteten oder ungenauen Ergebnissen führt. Dieses Verhalten kann zu Fehlern führen, insbesondere bei Finanzanwendungen oder Szenarien, die eine hohe Genauigkeit erfordern.
In diesem Artikel werden wir uns mit der Grundursache dieses Problems befassen, erklären, wie man es vermeidet, ein funktionierendes Beispiel bereitstellen und untersuchen, ob neuere Java-Versionen bessere Alternativen bieten.
Der Double-Datentyp in Java folgt dem Gleitkommazahl-Operationsstandard IEEE 754. Es stellt Zahlen im Binärformat dar mit:
Diese binäre Darstellung führt zu Einschränkungen:
Zum Beispiel im Binärformat:
Vorgänge mit Doppelvorgängen können zu Fehlern führen:
Dieses Verhalten ist der Gleitkomma-Arithmetik eigen und nicht nur in Java zu finden.
Hier ist ein Beispiel, das das Problem verdeutlicht:
<code class="language-java">public class DoublePrecisionLoss { public static void main(String[] args) { double num1 = 0.1; double num2 = 0.2; double sum = num1 + num2; System.out.println("预期和:0.3"); System.out.println("实际和:" + sum); // 比较 if (sum == 0.3) { System.out.println("和等于0.3"); } else { System.out.println("和不等于0.3"); } } }</code>
Ausgabe:
<code>预期和:0.3 实际和:0.30000000000000004 和不等于0.3</code>
Das Ergebnis 0,30000000000000004 verdeutlicht den Rundungsfehler, der durch die binäre Darstellung verursacht wird. Selbst geringfügige Unterschiede können in kritischen Systemen zu großen Problemen führen.
Die BigDecimal-Klasse in Java bietet Arithmetik mit beliebiger Genauigkeit und eignet sich daher ideal für Szenarien, die eine hohe Präzision erfordern (z. B. Finanzberechnungen).
<code class="language-java">import java.math.BigDecimal; public class BigDecimalExample { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("0.1"); BigDecimal num2 = new BigDecimal("0.2"); BigDecimal sum = num1.add(num2); System.out.println("预期和:0.3"); System.out.println("实际和:" + sum); // 比较 if (sum.compareTo(new BigDecimal("0.3")) == 0) { System.out.println("和等于0.3"); } else { System.out.println("和不等于0.3"); } } }</code>
Ausgabe:
<code>预期和:0.3 实际和:0.3 和等于0.3</code>
Durch die Verwendung von BigDecimal werden Präzisionsprobleme beseitigt und Vergleiche führen zu korrekten Ergebnissen.
Eine andere Möglichkeit, mit Präzisionsverlusten umzugehen, besteht darin, Gleitkommazahlen mit einer Toleranz (Epsilon) zu vergleichen. Diese Methode prüft, ob die Zahlen „nahe genug“ liegen, anstatt sich auf exakte Gleichheit zu verlassen.
<code class="language-java">public class EpsilonComparison { public static void main(String[] args) { double num1 = 0.1; double num2 = 0.2; double sum = num1 + num2; double epsilon = 1e-9; // 定义一个小的容差值 System.out.println("预期和:0.3"); System.out.println("实际和:" + sum); // 使用epsilon进行比较 if (Math.abs(sum - 0.3) < epsilon) { System.out.println("和大约等于0.3"); } else { System.out.println("和不等于0.3"); } } }</code>
Ausgabe:
<code class="language-java">public class DoublePrecisionLoss { public static void main(String[] args) { double num1 = 0.1; double num2 = 0.2; double sum = num1 + num2; System.out.println("预期和:0.3"); System.out.println("实际和:" + sum); // 比较 if (sum == 0.3) { System.out.println("和等于0.3"); } else { System.out.println("和不等于0.3"); } } }</code>
Beispiel: Verwenden Sie Precision.equals, um
zu vergleichen<code>预期和:0.3 实际和:0.30000000000000004 和不等于0.3</code>
Warum sollten Sie Apache Commons Math verwenden?
<code class="language-java">import java.math.BigDecimal; public class BigDecimalExample { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("0.1"); BigDecimal num2 = new BigDecimal("0.2"); BigDecimal sum = num1.add(num2); System.out.println("预期和:0.3"); System.out.println("实际和:" + sum); // 比较 if (sum.compareTo(new BigDecimal("0.3")) == 0) { System.out.println("和等于0.3"); } else { System.out.println("和不等于0.3"); } } }</code>
Das obige ist der detaillierte Inhalt vonWarum doppelt doppelt Präzision verliert und wie man es in Java vermeidet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!