2010-03-04 6 views
60

Ich habe Code, um den prozentualen Unterschied zwischen 2 Zahlen zu berechnen - (oldNum - newNum)/oldNum * 100; - wo beide Zahlen sind double s. Ich erwartete, dass ich eine Art Checking/Exception-Behandlung für den Fall, dass OldNum 0 ist, hinzufügen musste. Wenn ich jedoch einen Testlauf mit Werten von 0.0 für OldNum und NewNum machte, wurde die Ausführung fortgesetzt, als wäre nichts passiert und kein Fehler wurde ausgelöst. Das Ausführen dieses Codes mit int s würde definitiv eine arithmetische Division durch Null-Ausnahme verursachen. Warum ignoriert Java es, wenn es zu double s kommt?Warum wirft Java keine Exception, wenn es durch 0,0 geteilt wird?

+4

Gute Frage - die Inkonsistenz zwischen Integer und Double-Verhalten fügt Verwirrung und Ärger hinzu. –

+2

mögliches Duplikat von [Warum gibt Division durch Null mit Fließkommazahlen (oder doppelten Genauigkeitszahlen) java.lang.ArithmeticException:/nicht durch null in Java] (http://stackoverflow.com/questions/12954193/why-does- division-by-zero-mit-floating-point-double-precision-numbers-not) – Raedwald

+2

@Raedwald - wenn man bedenkt, dass diese Frage 2 1/2 Jahre vor der von Ihnen verlinkten gestellt wurde, würde ich sagen, dass die Frage a ist (möglich) Duplikat davon :) – froadie

Antwort

42

Das Ergebnis der Division durch Null, mathematisch gesprochen, undefinierten, die mit einem Schwimmer ausgedrückt werden kann/double (als NaN - keine Zahl), ist es jedoch nicht falsch in jedem grundlegenden Sinn.

Da eine ganze Zahl einen bestimmten numerischen Wert enthalten muss, muss ein Fehler bei der Division durch Null ausgelöst werden.

+6

Genau. Dies ist in der Java Language Spec hier definiert: http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 –

+1

Ich habe versucht, das Ergebnis auszugeben, und es ist ein NaN-Wert. Bedeutet das, dass Ints NaN nicht halten können? – froadie

+1

, aber dies ist der Fall von 0,0/0,0, was NaN ist. –

4

Die Art und Weise, wie ein Double gespeichert wird, unterscheidet sich ziemlich von einem Int. Eine ausführlichere Erläuterung dazu, wie Java doppelte Berechnungen durchführt, finden Sie unter http://firstclassthoughts.co.uk/java/traps/java_double_traps.html. Sie sollten auch die Gleitkommazahlen lesen, insbesondere das Konzept Not a Number (NaN).

Wenn Sie mehr über Fließkommadarstellung lernen möchten, rate ich Ihnen, this document (Word-Format, sorry) zu lesen. Es befasst sich mit der binären Darstellung von Zahlen, die für Ihr Verständnis hilfreich sein kann.

101

Java float und double Arten, wie so ziemlich jede andere Sprache gibt (und so ziemlich jede Hardware-FP-Einheit), implementieren den IEEE 754 Standard für Fließkommaberechnungen, die Division durch Null beauftragt einen speziellen „unendlich“ Wert zurückgeben . Eine Ausnahme zu werfen würde diesen Standard verletzen.

Ganzzahlarithmetik (implementiert als two's complement Darstellung von Java und den meisten anderen Sprachen und Hardware) ist anders und hat keine speziellen Unendlich- oder NaN-Werte, daher ist das Auslösen von Ausnahmen ein nützliches Verhalten.

+3

Die richtige Antwort auf diese Frage sollte dies sein. Ich musste wissen, warum 'float' und' double' keine Exceptions verursachen. Vielen Dank. –

+1

Dies sollte die richtige Antwort sein.Die aktuell als richtig markierte Antwort beantwortet weder die Frage, noch macht sie deutlich, dass Java IEEE 754 folgt. – Necrototem

3

Obwohl Java-Entwickler wissen über die Doppel primitive Art und Double Klasse, während Gleitkomma-Arithmetik tun sie zahlen nicht genug Aufmerksamkeit auf Double.INFINITY, NaN, -0.0 und andere Regeln, die die arithmetischen Berechnungen mit ihnen regieren.

Die einfache Antwort auf diese Frage ist, dass es ArithmeticException nicht werfen und Double.INFINITY zurückgeben wird. Beachten Sie auch, dass der Vergleich x == Double.NaN immer false ergibt, auch wenn x selbst ein NaN ist.

Um zu testen, ob x eine NaN ist, sollte man den Methodenaufruf Double.isNaN(x) verwenden, um zu überprüfen, ob die angegebene Zahl NaN ist oder nicht. Dies ist sehr nahe NULL in SQL.

Es kann hilfreich für Sie sein.

1

Wenn geteilt durch Null (0 oder 0,00)

  1. Wenn Sie mit dem 0 Doppel teilen, wird JVM zeigen Unendlichkeit.

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); }

    Console: Infinity

  2. Wenn Sie int von 0 dividieren, dann wird JVM arithmetische Ausnahme werfen.

    public static void main(String [] args){ int a=10; System.out.println(a/0); }

    Console: Exception in thread "main" java.lang.ArithmeticException:/by zero

  3. Aber wenn wir int um 0,0 dividieren, dann wird JVM zeigen Infinity:

    public static void main(String [] args){ int a=10; System.out.println(a/0.0); }

    Console: Infinity

Das liegt daran, dass JVM automatisch Cast Int in Double eingibt, sodass wir unendlich anstelle von ArithmeticException erhalten.

Verwandte Themen