# Warum X/0 = Infinity?



## Moch (20. Nov 2013)

Hallo,

Ich habe mal eine allgemeine Frage, die mich momentan aber einfach interessiert. Mir ist kürzlich ein Programm zerschossen, weil das Programm (durch einen Implementierungsfehler meinerseits) heimlich durch 0 geteilt hat.
Nun hat - für mich - die Fehlerursache recht lange gedauert, da der Wert 'Infinity' recht lange durch das System geschleift wurde, irgendwann eine NaN ausgelößt hat, die wieder später zur Exception geführt hat

Wie gesagt: Natürlich ist das ganze mein Fehler, da ich diesen Fall nicht vorhergesehen und auch nicht abgefangen habe.

Mich interessiert jetzt aber, warum das in Java (und offenbar auch einigen anderen Hochsprachen) so festgelegt wurde.
Also für mich in meiner begrenzten Sicht, klingt es eher logisch, wenn eine Exception geworfen wird <- ich meine "Fangen" könnte der Programmierer sie ja immer noch.

Hat das einen speziellen Sinn oder Nutzen, dass stattdessen der (mathematisch ja eigentlich auch nicht haltbare, oder?) Infinity-Wert gesetzt wird?

Wie gesagt: Das ist keine Kritik an der Sprache selbst oder so, sondern einfach nur Interesse an der Thematik.

Gruß
Moch


----------



## Gucky (20. Nov 2013)

Was sollte denn sonst gesetzt werden? Mathematisch gibt es keine Genaue Definition. Fakt ist aber, dass je näher der Teiler an die null herankommt, desto größer ist auch das Ergebnis.
Man hätte es auch so machen können, dass es dann knallt oder eine Exception geworfen wird aber das Knallen hätte womöglich Schäden hervorrufen können (oder es wäre praktisch unmöglich gewesen den Fehler zu finden, da das Programm einfach kommentarlos abbrechen würde) und eine Exception zu werfen war wohl zu umständlich (auch verständlich. Wenn sich die Exceptions in die kleinsten Dinge einklinkten müsste die ganze Zeit ein Überprüfer mitlaufen).

Auch möglich wäre, dass einfach der höchstmögliche Wert für diese Variable gesetzt würde. Aber man hat sich für den infinity-Wert entschieden (, der zwar keinen direkten Beweis hat aber es hat sich dennoch so eingebürgert, dass eine Division mit null im Teiler entweder keine Definition hat (knallen; Exception) oder eben unendlich ergibt (infinity-Wert)).


----------



## Lars789852 (20. Nov 2013)

Hallo,

der Computer hält die Null für eine unendlich kleine Zahl. Und wenn man durch 0 teilt, bildet man einen Kehrwert von der Null, also eine unendlich große Zahl. In der Mathematik ist eine Division durch 0 voll verboten. In Java ist die Division durch 0 auch voll verboten (ArithmeticException), durch 0.0 aber nicht (wegen float).

Im Prinzip musst du dir nur vorstellen, wie oft die 0 in x passt... sehr oft.

Wenn eine float oder double Variable den Wert Infinity hat, dann sitzt sie sozusagen da fest. Da kann man mit herumrechnen, wie man möchte, das Ergebnis wird immer Infinity bleiben, es sei denn, man teilt durch irgendwas, was auch Infinity beinhaltet.


----------



## Ikaron (24. Nov 2013)

Das kannst du dir ganz einfach mit der Funktion f(x) = 1/x erklären, in dem du Grenzwert für x -> 0 berechnest. Du wirst merken, wenn du von "rechts", also von den positiven Zahlen, dich gegen 0 annäherst, das Ergebnis (unendlich) groß wird. Von links wird es (unendlich) klein. In beiden Fällen ist x unendlich, nur ein mal positiv und 1x negativ. Somit ist x = 0 eine Definitionslücke, weil die Funktion an dieser Stelle 2 Werte erhält. Über die Symmetrie könnte man allerdings argumentieren, dass auch der Punkt 0/0 auf dem Graphen liegen muss, daraus resultierend müssten alle Punkte (0/y) y Element IR auf dem Graphen liegen => Keine Funktion mehr (an dieser Stelle). In Java wurde einfach festgelegt, dass man annimmt, dass da unendlich rauskommt, man hat sich entschieden, die positive Unendlichkeit zu verwenden.


----------



## Tobse (24. Nov 2013)

Wie Lars schon gesagt hat, etwas "unendlich kleines" passt in fast alles so oft rein, dass nur die Unendlichkeit es beschreiben kann. die Mathematische schreibweise ist ja nicht umsonst [c]1/x -> unendlich für x -> 0[/c].

warum keine Exception fliegt kann ich mir so erklären: Man müsste jeden Code, der etwas ausrechnet in ein Try-Catch einkasteln. Das ist für 1-2 mal sicher kein Problem aber wenns viel wird nervt es einfach nurnoch.


----------



## Natac (25. Nov 2013)

Für Ganzzahlen fliegt eine Exception. Warum also schreibt ihr sowas wie "wäre zu umständlich" und "müsste man in try-catch packen"!? :bahnhof:

A) Die JVM prüft jede Operation, die potentiell gefährlich ist. Sei das nun Zugriff auf ein Array (IndexOutOfBoundsException) oder das teilen einer Ganzzahl druch 0 (ArithmeticException). Und ja, JAVA prüft das IMMER. Und nein, das ist nicht zu umständlich.

B) Solche Exceptions sind vom Type "RuntimeException" und erzwingen keinen try-catch-Block.

C) Dass beim Teilen einer Fließkommazahl durch 0 unendlich rauskommt und keine Exception geworfen wird, ist wahrscheinlich einfach so spezifiziert. Genau wie spezifiziert ist, dass NaN ungleich sich selbst ist. Ob diese Spezifikation Sinn macht oder intuitiv ist, steht auf einem anderen Blatt. :rtfm: 

Ich bin mir bewusst, dass das deine Frage nur unzureichend beantwortet. Aber bei dem Schwachfug, der hier geschrieben wurde, musste ich wirklich mal dazwischen gehen (insbesonderen Punkte A) und B) ).


----------



## Tobse (25. Nov 2013)

Natac hat gesagt.:


> Für Ganzzahlen fliegt eine Exception. Warum also schreibt ihr sowas wie "wäre zu umständlich" und "müsste man in try-catch packen"!? :bahnhof:
> 
> A) Die JVM prüft jede Operation, die potentiell gefährlich ist. Sei das nun Zugriff auf ein Array (IndexOutOfBoundsException) oder das teilen einer Ganzzahl druch 0 (ArithmeticException). Und ja, JAVA prüft das IMMER. Und nein, das ist nicht zu umständlich.
> 
> B) Solche Exceptions sind vom Type "RuntimeException" und erzwingen keinen try-catch-Block.



wann schreibt man denn schon [c]int a = b / c;[/c]? Normalerweise ist es [c]float a = b / c;[/c] weil Divisionen selten ganzzahlige ergebnisse haben (ausser in Spezialfällen). Denn bei [c]float a = b / c;[/c] fliegt keine Exception, ebenso wenig wie bei [c]int a = (int) Math.round((float) b / c);[/c].
Und seien wir mal ehrlich: nur weil der Compiler das try-catch nicht erzwingt muss man auf die Exception gefasst sein weil sie in der Laufzeit einiges an "Schaden" anrichten kann.


----------



## rme (25. Nov 2013)

Ich vermeide Gleitkommazahlen, wo immer es geht. Bei mir kommen also sehr oft Divisionen vor, obwohl beide Typen int sind. Wenn ich Nachkommastellen brauche, verwende ich Festkommaarithmetik. Der Grund ist, dass Gleitkommazahlen mathematisch keinen vernünftigen Körper bilden, die Operationen sind nicht einmal assoziativ, man darf == nicht verwenden und vieles weitere.. 

An der Uni gibt's einen eigenen Fachbereich (Numerik) mit vielen Vorlesungen, die sich nur damit befassen, dass und warum man Gleitkommazahlen vermeiden sollte - und wie man vorgehen muss, wenn man nicht drumrum kommt.


----------



## Tobse (25. Nov 2013)

rme hat gesagt.:


> Ich vermeide Gleitkommazahlen, wo immer es geht. Bei mir kommen also sehr oft Divisionen vor, obwohl beide Typen int sind. Wenn ich Nachkommastellen brauche, verwende ich Festkommaarithmetik. Der Grund ist, dass Gleitkommazahlen mathematisch keinen vernünftigen Körper bilden, die Operationen sind nicht einmal assoziativ, man darf == nicht verwenden und vieles weitere..
> 
> An der Uni gibt's einen eigenen Fachbereich (Numerik) mit vielen Vorlesungen, die sich nur damit befassen, dass und warum man Gleitkommazahlen vermeiden sollte - und wie man vorgehen muss, wenn man nicht drumrum kommt.



Du würdest dir dabnn aber (auch in hinsicht auf die Exceptions) mit 
	
	
	
	





```
(int) Math.round((float) b / c);
```
 leichter tun. Und klar, man kann auch einfach alles mit 2 Zehnerpotenzen mehr rechnen und das Ergebnis entsprechend teilen.


----------



## Natac (26. Nov 2013)

Tobse hat gesagt.:


> Und seien wir mal ehrlich: nur weil der Compiler das try-catch nicht erzwingt muss man auf die Exception gefasst sein weil sie in der Laufzeit einiges an "Schaden" anrichten kann.


Nein! Wenn man sich nicht sein kann, dass der Divisor ungleich 0 ist, dann fragt man das vorher ab und gibt eine entsprechende Fehlermeldung zurück (und das möglichst noch in der GUI). 

Du fährst mit nem Auto doch auch erst zum TÜV anstatt einfach loszufahren und zu gucken ob es gut geht!?


----------



## Tobse (26. Nov 2013)

Natac hat gesagt.:


> Nein! Wenn man sich nicht sein kann, dass der Divisor ungleich 0 ist, dann fragt man das vorher ab und gibt eine entsprechende Fehlermeldung zurück (und das möglichst noch in der GUI).
> 
> Du fährst mit nem Auto doch auch erst zum TÜV anstatt einfach loszufahren und zu gucken ob es gut geht!?



Ich kaufe kein Auto ohne TÜV. Die Gui prüft die Eingabe, die methode selbst nicht (Zumindest in meinen Implementationen).

[EDIT]
Wenn der Divisor ein Ergebnis von Rechnungen ist, welche die Methode selbst durchführt und die Diskriminante für den Term nicht in der Doku steht, prüfe ich selbst, ja.
[/EDIT]


----------

