Read Online (Free) relies on page scans, which are not currently available to screen readers. To access this article, please contact JSTOR User Support . We'll provide a PDF copy for your screen reader. With a personal account, you can read up to 100 articles each month for free. Show
Already have an account? Log in Monthly Plan
Yearly Plan
Log in through your institution Purchase a PDFPurchase this article for $32.00 USD. How does it work?
journal article Über Leibniz' UnendlichkeitstheorieStudia Leibnitiana Bd. 23, H. 2 (1991) , pp. 151-169 (19 pages) Published By: Franz Steiner Verlag https://www.jstor.org/stable/40694174 Read and download Log in through your school or library Alternate access options For independent researchers Read Online Read 100 articles/month free Subscribe to JPASS Unlimited reading + 10 downloads Purchase article $32.00 - Download now and later Abstract Leibniz's theory of infinity contains many theoretically difficult aspects. Until today only some of them have been systematically studied by mathematicians and philosophers. For instance Leibniz didn't only discover some of the paradoxical properties of an infinite set: he also discovered that a classification of four kinds of infinity is possible and that their properties can be investigated. This article reconstructs this classification and these properties. The metaphysical implications in Leibniz's system and some of the possible developments of these theories in the modern philosophy of mathematics are also investigated. Journal Information The Journal of History of Philosophy and Science, founded in 1969, is the organ of the Gottfried Wilhelm Leibniz Society. She explores the work and thought of Leibniz and serves the knowledge of the intellectual and ideological context of his epoch from the Renaissance to the Enlightenment. The periodical is published by an international group of scholars of various disciplines (philosophers, mathematicians and historians) and includes contributions in German, English and French, which are selected in a peer review process. Die Zeitschrift für Geschichte der Philosophie und der Wissenschaften, begründet 1969, ist das Organ der Gottfried-Wilhelm-Leibniz-Gesellschaft. Sie erforscht Werk und Denken von Leibniz und dient der Erkenntnis der geistes- und ideengeschichtlichen Zusammenhänge seiner Epoche von der Renaissance bis zur Aufklärung. Das Periodikum wird von einem internationalen Gelehrtenkreis verschiedener Disziplinen (Philosophen, Mathematikern und Historikern) herausgegeben und umfasst Beiträge in deutscher, englischer und französischer Sprache, die in einem peer review-Verfahren ausgewählt werden. Publisher Information Franz Steiner is one of Germany's most prominent academic publishing houses. Our focal point is ancient history, but also social and economic history, as well as history of science; furthermore regional studies, Eastern European history and transatlantic studies. We oversee more than 150 serial publications as well as 28 periodicals and publish such renowned series as Historia, Hermes and Archiv für Rechts- und Sozialphilosophie. We only publish those projects which proved their academic value in external anonymous peer assessments. Rights & Usage This item is part of a JSTOR Collection. Dieses Kapitel enthält Abschnitte für mehrere Varianten, die teilweise geprüft oder ergänzt werden müssen. In diesem Kapitel erhalten Sie genauere Erläuterungen zu denjenigen einfachen Datentypen, mit denen Dezimalzahlen verarbeitet werden. Überblick[Bearbeiten]Die folgende Tabelle nennt zu jedem Datentyp, der für eine Dezimalzahl steht, den Standardwert sowie das mögliche Minimum und Maximum. Als Postfix oder Suffix wird ein Zeichen genannt, das an den Wert angehängt wird, um den Typ zu kennzeichnen. Alle diese Typen gehören zu den vorgeschriebenen Standardtypen (den "CLS-kompatiblen") und sind deshalb fett gedruckt.
Wie zu sehen ist, unterscheiden sich diese Typen sowohl im Wertebereich als auch in der Genauigkeit. Dies wird unter Hinweise genauer erläutert, ebenso wie die Spalte "unendlich". Mit "E38" wird die wissenschaftliche Schreibweise benutzt. Das Single-Maximum bedeutet also eine Zahl mit maximal 39 Stellen, von denen aber nur die ersten 7 Stellen berücksichtigt werden:3,402823E38 Der folgende Code als Teil einer Main-Methode benutzt ein paar dieser Eigenschaften.
Bitte beachten Sie, dass innerhalb von Code immer der Punkt als Dezimaltrenner verwendet werden muss: C#-Quelltext Single d1 = Single.MinValue; Single d2 = d1 * d1; Double d3 = d1 * d1; Console.WriteLine(String.Format("Single = {0}" + Environment.NewLine + "Double = {1}", d2, d3)); Decimal m1 = 13.1m; Decimal m2 = m1 * 0.19m; Decimal m3 = m1 + m2; Console.WriteLine(String.Format("[Decimal] {0} + {1} = {2}", m1, m2, m3)); Double f4 = 0; Decimal m4 = 0; for(int x1 = 0; x1 < 10000; x1++) { f4 += 0.0001; m4 += 0.0001m; } Console.WriteLine(String.Format("decimal = {0}" + Environment.NewLine + "Double = {1}", m4, f4)); Console.ReadKey(); VB.NET-Quelltext Dim d1 As Single = Single.MinValue Dim d2 As Single = d1 * d1 Dim d3 As Double = d1 * d1 Console.WriteLine(String.Format("Single = {0}" _ + Environment.NewLine + "Double = {1}", d2, d3)) Dim m1 As Decimal = 13.1d Dim m2 As Decimal = m1 * 0.19d Dim m3 As Decimal = m1 + m2 Console.WriteLine(String.Format("[Decimal] {0} + {1} = {2}", m1, m2, m3)) Dim f4 As Double = 0.0 Dim m4 As Decimal = 0.0d For x1 As Integer = 1 To 10000 Step 1 f4 += 0.0001 m4 += 0.0001d Next x1 Console.WriteLine(String.Format("decimal = {0}" _ + Environment.NewLine + "Double = {1}", m4, f4)) Console.ReadKey() Single = +unendlich Double = 1,15792075433824E+77 [Decimal] 13,1 + 2,489 = 15,589 decimal = 1,0000 Double = 0,999999999999906 Bei direkter Ein- und Ausgabe von Werten hängen Dezimalzeichen und Tausendertrenner auch von der Installation des Rechners und der konkreten Formatierung ab. Hinweise[Bearbeiten]Bei diesen Datentypen handelt es sich um Gleitkommazahlen. Dies ist immer eine näherungsweise Darstellung einer reellen Zahl (in Exponentialdarstellung wie in der Tabelle). Bei Single und Double muss man mit dieser Ungenauigkeit leben; bei Decimal sorgt die interne Verarbeitung der Daten für größere Genauigkeit. Unendlich u.a.[Bearbeiten]Für Single und Double gibt es die folgenden Eigenschaften, was durch das Wort "definiert" in der obigen Spalte "unendlich" deutlich gemacht wird:
Dazu gibt es Prüfungen, ob ein Wert unendlich ist; dafür ändern wir das obige Beispiel leicht: C#-Quelltext Single d1 = Single.MinValue; Single d2 = d1 * d1; Double d3 = d1 * d1; Console.WriteLine(String.Format("d1 unendlich: {0:f} {1}" + Environment.NewLine + "d2 +unendlich: {2:f} {3}" + Environment.NewLine + "d3 -unendlich: {4:f} {5}", d1, Single.IsInfinity(d1), d2, Single.IsPositiveInfinity(d2), d3, Double.IsNegativeInfinity(d3))); Console.ReadKey(); VB.NET-Quelltext Dim d1 As Single = Single.MinValue Dim d2 As Single = d1 * d1 Dim d3 As Double = d1 * d1 Console.WriteLine(String.Format("d1 unendlich: {0:f} {1}" _ + Environment.NewLine + "d2 +unendlich: {2:f} {3}" _ + Environment.NewLine + "d3 -unendlich: {4:f} {5}", _ d1, Single.IsInfinity(d1), _ d2, Single.IsPositiveInfinity(d2), _ d3, Double.IsNegativeInfinity(d3))) Console.ReadKey() d1 unendlich: -340282300000000000000000000000000000000,00 False d2 +unendlich: +unendlich True d3 -unendlich: 115792075433824000000000000000000000000000000000000000000000000000000000000000,00 False
In der Praxis sind diese Situationen eigentlich selten von Bedeutung. Sie müssen aber den folgenden Unterschied bei unzulässigen Berechnungen beachten:
Sie müssen deshalb in allen Fällen selbst eine entsprechende Fehlerbehandlung vorbereiten. Genauigkeit[Bearbeiten]Schon der letzte Teil des einleitenden Beispiels machte deutlich, dass Single und Double ungenau rechnen. Dies ist eine direkte Auswirkung davon, wie Dezimalzahlen von Computern verarbeitet werden. Schauen wir uns zwei einfache Beispiele an: C#-Quelltext Single d1 = 0.0003f / 3 - 0.0001f; Double d2 = 0.0003 / 3 - 0.0001; Console.WriteLine(String.Format("d1 = {0} / gleich null: {1}", d1, d1 == 0)); Console.WriteLine(String.Format("d2 = {0} / gleich null: {1}", d2, d2 == 0)); Single d3 = 8.436713f; Single d4 = 8.4367131f; Console.WriteLine(String.Format("d3 = {0} / d4 = {1} / gleich: {2}", d3, d4, d3 == d4)); VB.NET-Quelltext Dim d1 As Single = 0.0003f / 3 - 0.0001f Dim d2 As Double = 0.0003 / 3 - 0.0001 Console.WriteLine(String.Format("d1 = {0} / gleich null: {1}", _ d1, d1 = 0)) Console.WriteLine(String.Format("d2 = {0} / gleich null: {1}", _ d2, d2 = 0)) Dim d3 As Single = 8.436713 Dim d4 As Single = 8.4367131 Console.WriteLine(String.Format("d3 = {0} / d4 = {1} / gleich: {2}", _ d3, d4, d3 = d4)) d1 = 7,275958E-12 / gleich null: False d2 = -1,35525271560688E-20 / gleich null: False d3 = 8,436713 / d4 = 8,436713 / gleich: True Die erste Rechnung sollte, wie man im Kopf ausrechnen kann oder direkt sieht, als Ergebnis 0 liefern. Tatsächlich gibt es bei Single und Double unterschiedliche Ergebnisse, die aber immer ungleich 0 sind. Bei Double ist der Wert um 8 Zehnerpotenzen näher an 0, was an der höheren Genauigkeit liegt; aber es bleibt ungleich 0. Der Vergleich zwischen d3 und d4 zeigt: Wegen der beschränkten Genauigkeit wird die letzte Dezimalstelle bei d4 von vornherein ignoriert. Beide Werte werden also als gleich angesehen.
Verfahren bei Ungenauigkeiten[Bearbeiten]Offensichtlich muss man sich Gedanken darüber machen, wie diese Ungenauigkeiten behandelt werden können:
Zum letzten Punkt gehören zwei Schritte, die im folgenden Code zusammengefasst werden. C#-Quelltext namespace Wikibooks.CSharp.ConsoleApp { class Program { static void Main(string[] args) { double epsilon = Epsilon(); Console.WriteLine(epsilon); Double d2 = 0.0003 / 3 - 0.0001; if( Math.Abs(d2 - 0.0) < epsilon ) Console.WriteLine("d2 ist nahezu gleich Null"); else Console.WriteLine("d2 ist wirklich ungleich Null"); Console.ReadKey(); } public static double Epsilon() { double tau = 1.0; double alt = 1.0; double neu = 0.0; while (neu != alt) { tau *= 0.5; neu = alt + tau; } return 2.0 * tau; } } } VB.NET-Quelltext Namespace Wikibooks.VBNet.ConsoleApp Module Program Sub Main() Dim epsilon As Double = CalcEpsilon() Console.WriteLine(epsilon) Dim d2 as Double = 0.0003 / 3 - 0.0001 if( Math.Abs(d2 - 0.0) < epsilon ) Console.WriteLine("d2 ist nahezu gleich Null") else Console.WriteLine("d2 ist wirklich ungleich Null") end if Console.ReadKey() End Sub Function CalcEpsilon() As Double Dim tau as Double = 1.0 Dim alt as Double = 1.0 Dim neu as Double = 0.0 While (neu <> alt) tau *= 0.5 neu = alt + tau End While Return 2.0 * tau End Function End Module End Namespace 2,22044604925031E-16 d2 ist nahezu gleich NullVergleich durch einen Näherungswert Die beiden Werte, die verglichen werden sollen – im Beispiel das Ergebnis der Rechnung und der konstante Wert 0.0 (der eigentlich überflüssig ist und nur zur Verdeutlichung hingeschrieben ist) – werden voneinander abgezogen; dann wird geprüft, ob der Absolutbetrag der Differenz kleiner ist als die zulässige Abweichung. Festlegung des NäherungswertesDieser Wert wird üblicherweise Epsilon genannt; er kann wie im Beispiel vorgegeben werden.[1] Diese Berechnung erfolgt am besten am Anfang des Programms einmalig; der Wert wird "irgendwo" zur wiederholten Verwendung gespeichert. Hinweis: Single.Epsilon und Double.Epsilon haben nichts damit zu tun; diese sind jeweils der kleinste mögliche Wert, der größer als 0 ist. Nebenbei gesagt: In der Praxis spielen diese Ungenauigkeiten oft keine Rolle. Man muss sich aber dieser Möglichkeit bewusst sein und darf nicht irgendwann erstaunt aufschreien: ".NET rechnet falsch!" Der Datentyp Decimal als Besonderheit[Bearbeiten]Zur Vermeidung der Ungenauigkeiten wurde der Datentyp Decimal eingeführt, dessen Werte intern anders gespeichert und verarbeitet wird als bei Single oder Double. Der Decimal-Wertetyp ist für finanzmathematische Berechnungen geeignet, bei denen zahlreiche signifikante Vor- und Nachkommastellen erforderlich sind und keine Rundungsfehler auftreten dürfen. Wie aus den obigen Beispielen deutlich wird, gibt es die für Single und Double beschriebenen Probleme beim Rechnen und Vergleichen bei Decimal nicht. Operationen[Bearbeiten]Für alle diese Datentypen stehen die folgenden Möglichkeiten zur Verfügung:
Mit dem letzten Schritt sind auch Vergleiche und Rechenoperationen zwischen Werte verschiedener Typen möglich. Grenzüberschreitung[Bearbeiten]Die bisherigen Beispiele zeigen schon, was passiert, wenn durch eine Rechnung oder Typumwandlung der maximale Wertebereich überschritten wird:
Ohne genauere Prüfungen können wir außerdem für Double-Werte feststellen:
Die beiden letzten Situationen werden im folgenden Beispiel gezeigt: C#-Quelltext // ein Double-Wert, der in den Single-Bereich passt Double d1 = 0.2468097531 * Single.MaxValue; Single s1 = (Single)d1; Console.WriteLine(d1); Console.WriteLine(s1); // ein zu großer Double-Wert Double d2 = 3.57902468 * Single.MaxValue; // der kleinste Double-Wert, der über Single hinausreicht Double dd = Single.MaxValue + Double.Epsilon; // die modulo-Operation anwenden Double d3 = d2 % dd; // das Ergebnis als Single vergleichen Single s2 = (Single)d3; Console.WriteLine(d2); Console.WriteLine(dd); Console.WriteLine(d3); Console.WriteLine(s2); VB.NET-Quelltext ' ein Double-Wert, der in den Single-Bereich passt Dim d1 As Double = 0.2468097531 * Single.MaxValue Dim s1 As Single = CSng(d1) Console.WriteLine(d1) Console.WriteLine(s1) ' ein zu großer Double-Wert Dim d2 As Double = 3.57902468 * Single.MaxValue ' der kleinste Double-Wert, der über Single hinausreicht Dim dd As Double = Single.MaxValue + Double.Epsilon ' die modulo-Operation anwenden Dim d3 As Double = d2 Mod dd ' das Ergebnis als Single vergleichen Dim s2 As Single = CSng(d3) Console.WriteLine(d2) Console.WriteLine(dd) Console.WriteLine(d3) Console.WriteLine(s2) // ein Double-Wert, der als Single-Wert verarbeitet werden kann 8,39850019581439E+37 8,3985E+37 // ein zu großer Double-Wert, der zu einem Single-Wert gemacht werden kann 1,21787891678761E+39 3,40282346638529E+38 1,97031876872023E+38 1,970319E+38 Sie sehen im ersten Fall und beim letzten Schritt, dass nur die Genauigkeit verloren geht. Ob diese Modulo-Funktion in der Praxis sinnvoll ist, lassen wir einmal offen; wahrscheinlich wird man eher eine glatte Zehnerpotenz dafür verwenden. Welchen Typ soll ich nehmen?[Bearbeiten]Wegen der Unterschiede zwischen Single bzw. Double sowie Decimal ist diese Entscheidung ganz einfach:
Zusammenfassung[Bearbeiten]Es gibt mehrere Datentypen für Dezimalzahlen, die sich im Wertebereich und in der Genauigkeit unterscheiden.
Wir können uns also merken:
Übungen[Bearbeiten]Hinweis: Wenn hier von Datentypen gesprochen wird, sind immer die drei hier behandelten Typen für Dezimalzahlen gemeint. Welche der folgenden Aussagen sind richtig, welche sind falsch?
Welche Datentypen können die folgende Werte bearbeiten? Bitte geben Sie jeweils an, ob die Bearbeitung genau oder mit Rundung erfolgt. Mehrere Antworten sind möglich. Der Punkt ist als Dezimaltrenner zu verstehen.
Welche der folgenden Aufgaben kann ein genaues Ergebnis liefern, welche nicht?
Ein Programm soll zwei verschiedene komplizierte Berechnungen mit Double-Werten ausführen. Wie ist die Prüfung vorzunehmen, ob die beiden Berechnungen dasselbe Ergebnis liefern? Lösungen Die Aussagen 1, 2 sind richtig, die Aussagen 3, 4, 5 sind falsch.
Aufgaben 1, 4, 7 werden immer genau berechnet. Die Lösung von Aufgabe 3 ist wegen der vorgegebenen Genauigkeit des Datentyps immer ungenau. Die Ergebnisse zu den Aufgaben 2, 5, 6 können wegen Rundungsfehlern ungenau sein.
Es kann auf jeden Fall zu Rundungsfehlern kommen. Deshalb kann keine exakte Gleichheit, sondern nur eine näherungsweise Gleichheit geprüft werden. Dies geht mit einem Verfahren wie folgt: if( Math.Abs(ergebnis1 - ergebnis2) < epsilon )
|