Hallo werte Kollegen und Kolleginnen Schlangenbeschwörer
Ich mach's kurz. Ich bin blutiger Anfänger und etwas geht da nicht in meinen Kopf:
a = 0
while a != 10:
a += 1
print a
else:
print 'a ist jetzt 10'
soweit, so gut - das funzt sogar glaub' ich. Aber warum zum was-auch-immer geht das nicht mit Floats..?!
a = 0
while a != 10:
a += 0.1
print a
else:
print 'a ist jetzt 10'
dies gibt eine Endlosschleife und der rechnet immer 0.1 dazu und gibt den Wert aus, bis... ...wohl bis mal der Strom ausfällt oder das OS streikt.
WARUM??? Es ist auch vollkommen egal, ob ich alle Werte bereits im Vorfeld als Floats definiere (also 0.0 und 10.0) - es geht auch dann nicht.
Auch wenn's Euch banal erscheint: Ich schnall's einfach nicht und wäre echt froh, wenn mich jemand ein wenig erleuchten könnte...
Im Vorfeld merci 1000,
Thomas
Ints und Floats - so verschieden..?
- Don Polettone
- User
- Beiträge: 115
- Registriert: Dienstag 23. November 2010, 20:26
- Wohnort: Schweiz
Willkommen im Forum!
Das Problem mit floats ist, dass sie nicht eine beliebige Genauigkeit haben. Siehe zum Beispiel dieses Beispiel:
wenn du jetzt diese Zahl auf Gleichheit prüfen würdest, wäre es nicht 0.1
Prüfe darum immer einen Bereich oder grösser als (oder kleiner als).
Das Problem mit floats ist, dass sie nicht eine beliebige Genauigkeit haben. Siehe zum Beispiel dieses Beispiel:
Code: Alles auswählen
In [11]: 10 - 9.9
Out[11]: 0.099999999999999645
Code: Alles auswählen
In [12]: 10 - 9.9 == 0.1
Out[12]: False
- Don Polettone
- User
- Beiträge: 115
- Registriert: Dienstag 23. November 2010, 20:26
- Wohnort: Schweiz
Hey besten Dank für die Antwort erst mal
Aber mit Verlaub:
Wie soll ich in einer Programmiersprache, welche nicht mal 10 - 0.1 so rechnen kann, dass das Ergebnis 9.9 beträgt, ein Programm schreiben..? Das ist nicht Euer Ernst, oder..? Ich meine, jeder Programmierer muss doch ständig Sachen errechnen lassen - und diese sind wohl in den allermeisten Fällen um ein Tausendfaches komplizierter als diese simple Rechnung, nicht? Das Zeug muss doch stimmen, sonst kann man ja nicht programmieren?? Ich seh's nicht mehr...
Was tut Ihr denn, wenn Ihr diese Rechnung im Programm haben MÜSST? Muss man immer angeben, auf wie viele Stellen gerundet werden soll?
erschüttert, desorientiert und der Verzweiflung nahe:
Thomas
Aber mit Verlaub:
Wie soll ich in einer Programmiersprache, welche nicht mal 10 - 0.1 so rechnen kann, dass das Ergebnis 9.9 beträgt, ein Programm schreiben..? Das ist nicht Euer Ernst, oder..? Ich meine, jeder Programmierer muss doch ständig Sachen errechnen lassen - und diese sind wohl in den allermeisten Fällen um ein Tausendfaches komplizierter als diese simple Rechnung, nicht? Das Zeug muss doch stimmen, sonst kann man ja nicht programmieren?? Ich seh's nicht mehr...
Was tut Ihr denn, wenn Ihr diese Rechnung im Programm haben MÜSST? Muss man immer angeben, auf wie viele Stellen gerundet werden soll?
erschüttert, desorientiert und der Verzweiflung nahe:
Thomas
Es gibt das modul Decimal.
Das Problem liegt am Binärsystem, nicht an der Programmiersprache!
Das Problem liegt am Binärsystem, nicht an der Programmiersprache!
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
- Don Polettone
- User
- Beiträge: 115
- Registriert: Dienstag 23. November 2010, 20:26
- Wohnort: Schweiz
wow, krass...
danke
danke
Versuch mal 1/3 genau zu schreiben. Da bekommst du auch nur 0,33333...
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
@Henry Jones Jr.: Das hat nicht viel mit der Programmiersprache zu tun, sondern ist halt Grundsätzlich ein Problem mit Fliesskommazahlen. Die haben a) keine beliebige Genauigkeit, und werden b) in einem Zahlensystem (binär) gespeichert bei dem andere "Dezimalbrüche" nicht endlich genau beschrieben werden können, als im Dezimalsystem. 0.1 lässt sich zum Beispiel nicht genau speichern, das Ergebnis von 1/3 dagegen schon.
Man kann kompliziertere Sachen berechnen, aber eben nicht genau und was eben richtig problematisch wird, sind genaue Vergleiche. Die darf man halt nicht machen, sonst passieren solche Sachen wie Deine Endlosschleife. Das ist halt so. Und in den letzten paar Jahrzehnten haben die Leute es ja auch geschafft damit zu programmieren.
Wenn ich so eine Schleife haben "muss", dann kann ich das halt nicht durch wiederholte Addition machen, wo bei jedem Additionsschritt wieder etwas mehr Ungenauigkeit in das Zwischenergebnis kommt. Nochmal was um Dich zu "erschrecken":
0.1 wird etwas grösser gespeichert als eine tatsächliche 0.1:
Wenn man jetzt 10 dieser Zahlen aufaddiert, könnte man ja auf die Idee kommen, das Ergebnis ist grösser als 1. Überraschung:
Und Runden nützt nichts, den 0.1 kann nun einmal intern nicht genau dargestellt werden. Jedenfalls nicht mit dem Fliesskommaformat, welches der Prozessor versteht und mit dem er schnell rechnen kann.
Man kann kompliziertere Sachen berechnen, aber eben nicht genau und was eben richtig problematisch wird, sind genaue Vergleiche. Die darf man halt nicht machen, sonst passieren solche Sachen wie Deine Endlosschleife. Das ist halt so. Und in den letzten paar Jahrzehnten haben die Leute es ja auch geschafft damit zu programmieren.
Wenn ich so eine Schleife haben "muss", dann kann ich das halt nicht durch wiederholte Addition machen, wo bei jedem Additionsschritt wieder etwas mehr Ungenauigkeit in das Zwischenergebnis kommt. Nochmal was um Dich zu "erschrecken":
0.1 wird etwas grösser gespeichert als eine tatsächliche 0.1:
Code: Alles auswählen
In [171]: 0.1
Out[171]: 0.10000000000000001
Code: Alles auswählen
In [172]: sum([0.1] * 10)
Out[172]: 0.99999999999999989
zum Nachlesen:
http://tutorial.pocoo.org/floatingpoint.html
http://tutorial.pocoo.org/floatingpoint.html
- Don Polettone
- User
- Beiträge: 115
- Registriert: Dienstag 23. November 2010, 20:26
- Wohnort: Schweiz
ist ja hammerhart!
Vielen Dank. Ich hatte ja keine Ahnung...
willkommen in der Matrix
Vielen Dank. Ich hatte ja keine Ahnung...
willkommen in der Matrix
Ich code, also bin ich.
Wenn du noch mehr Hintergrund haben möchtest, dann lies mal in Wikipedia den Artikel über Gleitkommazahlen. Der erste Satz sagt eigentlich schon alles: "Eine Gleitkommazahl (auch Gleitpunktzahl oder Fließkommazahl; engl. floating point number) ist eine approximative Darstellung einer reellen Zahl". Es ist also auf jeden Fall nur eine Näherung. Ganz böse sind dann solche Dinge wie die Ungültigkeit des Assoziativgesetzes.Henry Jones Jr. hat geschrieben:ist ja hammerhart!
Das bereits erwähnte Decimal-Modul schafft in Python Abhilfe. Hier sind die Berechnungen allerdings nicht mehr in Hardware (Prozessor) gegossen, so dass du dir durch die erhöhte Genauigkeit Performanceeinbußen einhandelst.