Seite 1 von 1
Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 10:07
von duodiscus
Hallo zusammen,
ich möchte eine Funktion erstellen, die float Zahlen von 0.00 bis 0.50 in Schritten von 0.05 in eine Liste gibt und die ich danach ausgeben kann. Danach möchte ich die Quadrate dieser Zahlen ebenfalls ausgeben lassen. Das Problem das ich zurzeit habe ist, das ich keinen richtigen Anfang hinbekomme, da ich mit der for - Schleife und dem range()-Befehl ja nur int-Werte hochzählen lassen kann hilft mir diese ja nicht weiter. Danach hatte ich die Idee mit einer while Schleife also: while zahl <= 0.50: , da weiß ich aber nicht wie ich dann die zahlen hochzählen lassen kann und später dann eine Berechnung damit ausführen kann. Könnt Ihr mir da etwas auf die Sprünge helfen?
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 10:20
von mutetella
@duodiscus
Vielleicht so?
Code: Alles auswählen
>>> def frange(start, stop, step, precise):
... while start < stop:
... yield round(start, precise)
... start += step
...
>>> list(frange(0.0, 0.5, 0.05, 2))
[0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5]
mutetella
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 10:26
von BlackJack
@duodiscus: Also bei einer ``while``-Schleife müsstest Du doch nur in jedem Schleifendurchlauf 0.05 zu `zahl` dazu addieren. Aber Achtung: Die Genauigkeit von Gleitkommazahlen ist begrenzt und 0.05 kann der Rechner in diesem Format nicht exakt speichern:
Code: Alles auswählen
In [5]: '%.50f' % 0.05
Out[5]: '0.05000000000000000277555756156289135105907917022705'
Das heisst man kann nicht genau 0.05 addieren und damit addiert man bei jedem Schritt einen kleinen Fehler dazu und wenn man das 10 mal macht, kommt da *nicht* 0.5 heraus. Und es wird noch schräger, denn obwohl der tatsächliche Wert von 0.05 etwas *grösser* ist, wie man oben sehen kann, ist das Ergebnis von 10 mal 0.05 aufaddieren *kleiner* als 0.5:
Code: Alles auswählen
In [6]: sum(0.05 for _ in xrange(10))
Out[6]: 0.49999999999999994
Willkommen in der lustigen Welt der Gleitkommazahlen in Rechnern.
Wenn man also eine ``while zahl < 0.5:``-Schleife schreibt die mit `zahl` gleich 0 anfängt und in jedem Durchlauf 0.05 dazu addiert, dann wird diese Schleife 11 mal durchlaufen. Was überraschend sein kann.
Darum addiert man nicht wiederholt in Schleifen Gleitkommawerte auf, wenn sich das vermeiden lässt. Und das lässt sich vermeiden, denn man kann ja über die ganzen Zahlen 0 bis 9 mit einer ``for``-Schleife iterieren und die entsprechende Zahl daraus berechnen. Das kann auch etwas ungenau sein, prinzipbedingt wegen den Gleitkommazahlen, aber es addieren sich so nicht die ungenauigkeiten aller vorherigen Schleifendurchläufe auf. Zum Vergleich:
Code: Alles auswählen
In [7]: zahl = 0
In [8]: zahlen = list()
In [9]: for _ in xrange(10):
...: zahl += 0.05
...: zahlen.append(zahl)
...:
In [10]: zahlen
Out[10]:
[0.05,
0.1,
0.15000000000000002,
0.2,
0.25,
0.3,
0.35,
0.39999999999999997,
0.44999999999999996,
0.49999999999999994]
In [11]: [0.05 * i for i in xrange(1, 11)]
Out[11]:
[0.05,
0.1,
0.15000000000000002,
0.2,
0.25,
0.30000000000000004,
0.35000000000000003,
0.4,
0.45,
0.5]
Mehr zum Thema Gleitkommazahlen:
http://floating-point-gui.de/
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 10:56
von mutetella
Um mal das aufzugreifen, was BlackJack geschrieben hat:
Code: Alles auswählen
>>> def frange(start, stop, step, digits):
... for i in xrange(int(stop/step)+1):
... yield round(i*step, digits)
...
>>> list(frange(0.0, 0.5, 0.05, 2))
[0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5]
mutetella
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 11:38
von duodiscus
Danke für deine sehr ausführliche Antwort. Ich habe jetzt ein wenig damit rumprobiert und habe das Ergebnis nach deiner zweiten Variante in eine Liste übertragen. Der Tip mit der Fehlerquote war top. Das werde ich mir für spätere Sachen merken!
Code: Alles auswählen
def f():
sammelstelle = [ ]
for e in range(1,11):
ergebnis = e*0.05
sammelstelle.append(ergebnis)
print(sammelstelle)
Wenn ich das Ergebnis aber statt in eine Liste vor zu einem Tupel formen möchte. Wie muss ich das syntaktisch da schreiben? Also Ergebnis in ein Tupel und das Tupel dann der Liste zuführen!
Der .append() Befehl gibt es ja nur bei Listen und funktioniert dort leider nicht.
Könnte man mir da nochmal weiterhelfen?
Ich habe nämlich danach dann vor, den jeweiligen durchlauf dann zu quadrieren, das Ergebnis wiederum dann auch einem Tupel zuführen und nachher der Liste hinzufügen.
Und ganz am Ende dann die Liste ausgeben.
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 12:13
von Sirius3
@duodiscus: warum der Schritt über ein Tuple? Listen sind ja dafür da, sich zu verändern, Tuple nicht.
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 12:17
von BlackJack
@duodiscus: Ich verstehe glaube ich die Frage nicht wirklich: Du willst Tupel die genau ein Element enthalten haben? Warum? Das wäre doch nur unnötig umständlich. Wenn Du die Zahl dann quadrierst und sowohl die jeweilige Zahl als auch deren Quadrat als Tupel in einer Liste speichern möchtest, kannst Du *dann* Tupel mit den beiden Werten erstellen. Denn bei zwei Werten machen Tupel Sinn zum zusammenfassen.
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 12:53
von duodiscus
@Sirius: Ich würde es nicht so machen. Aber in der Aufgabe die ich bearbeiten soll, ist es nunmal so vorgegeben.
@BlackJack: Nein du hast es missverstanden. Ich möchte es folgendermaßen bzw. soll es folgendermaßen aufbauen:
1. Zahlen von 0.0 bis 0.50 in 0.05er Schritten hochzählen lassen und diese Zahlen in einem Tupel ablegen.
2. Das Ergebnis dieser Zahlen zum Quadrat wiederum in ein weiteres/anderes Tupel geben.
3. Die Zahlen die hochgezählt wurden zur Basis 2 potenzieren, die Ergebnisse wiederum in ein weiteres Tupel geben.
4. Abschließend alle 3 Tupel in eine Liste geben.
5. Diese Liste dann zurückgeben.
Ich weiß jetzt nicht wie ich diese verschiedenen Tupel erstellen kann. Elemente einer Liste hinzufügen ist klar, aber wie die Ergebnisse in ein Tupel verwandeln?
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 13:22
von mcdwerner
@duodiscus:
Code: Alles auswählen
l = range(10)
type(l)
#<type 'list'>
t = tuple(l)
type(t)
#<type 'tuple'>
als kleiner Hinweis

Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 13:43
von BlackJack
Wobei das IMHO sinnfrei ist beziehungsweise sogar eine falsche Verwendung von Tupeln. Tupel verwendet man eher für Daten mit unterschiedlicher Bedeutung um die zu einem Objekt zusammen zu fassen. Also zum Beispiel Koordinaten oder einen Eintrag in einer Highscoreliste mit Punktanzahl und Name als Elemente. Das was Du da hast sind ja Daten wo jedes Element die gleiche Bedeutung hat — eine Zahl in der Sequenz.
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 16:14
von duodiscus
Aber die Aufgabe wurde mir eben so gestellt.

Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 16:35
von duodiscus
@mcdwerner:
Danke

Er gibt mir aber bei mir eine Fehlermeldung:
Code: Alles auswählen
for e in range(1,11):
a = e*0.05
ergebnis1 = tuple(a)
print(type(ergebnis1))
Code: Alles auswählen
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
f5()
File "/Users/A11.py", line 6, in f5
ergebnis1 = tuple(a)
TypeError: 'float' object is not iterable
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 16:47
von BlackJack
@duodiscus: Ja, man kann ja auch eine Zahl nicht in ein Tupel umwandeln. Genau was die Fehlermeldung sagt. Du musst an `tuple()` ein Objekt übergeben über das man iterieren kann. Also zum Beispiel eine Liste mit den Zahlen. Also erst eine Liste mit den Zahlen erstellen und *die* danach in ein Tupel überführen.
Das ist einer der Gründe warum Tupel für so etwas blöd sind: Man muss schon ein anderes Objekt haben, das alle Elemente liefert um daraus ein Tupel zu erstellen, denn Tupel können nach dem Erstellen nicht mehr verändert werden.
Edit: Wenn man nicht gerade Anfänger ist, würde man einen Generatorausdruck als Argument verwenden, das hält den Quelltext halbwegs erträglich und man erzeugt keine extra Liste. Zumindest nicht explizit, und intern kann die `tuple()`-Funktion das besser optimieren als man das mit einer Liste auf Python-Ebene selber tun könnte:
Code: Alles auswählen
In [4]: tuple(i * 0.5 for i in xrange(1, 11))
Out[4]: (0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0)
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Dienstag 29. April 2014, 17:11
von duodiscus
Habe jetzt eine Lösung. Mit der Umwandlung von Liste in Tupel. Und dann nachher wieder zurück. Gibt sicher noch andere Varianten, da diese Methode doch recht kompliziert ist. Aber sie funktioniert so...
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Mittwoch 30. April 2014, 13:57
von Heini
Ich nehme mal an du darfst kein numpy verwenden, oder? (Andernfalls fehlt bei der Aufgabe der pädagogische Effekt, nehme ich an.)
Code: Alles auswählen
import numpy
a=numpy.arange(0,51,5)/100.
b=tuple(a)
c=tuple(a**2)
print type(b), b
print type(c), c
Re: Rechenoperationen mit float Zahlen (Wertebereich)
Verfasst: Mittwoch 30. April 2014, 14:07
von BlackJack
Wobei ich bei Numpy wohl ``linspace(0, 0.5, 11)`` für `a` verwendet hätte.
