Seite 1 von 1

Zufallszahl mit 1 Kommastelle

Verfasst: Samstag 16. August 2008, 22:02
von theliquidwave
Hi -.-
Also, ich scheine gerade irgendwie auf dem Schlauch stehen :x
Ich möchte 2 Zufallszahlen von 1.0 bis 2.0 haben, die nur 1 Kommastelle besitzen.
Ich habe es bis jetzt so gelöst:

Code: Alles auswählen

	randzahlen = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
	speed = [round(random.choice(randzahlen), 1), round(random.choice(randzahlen), 1)]
	print speed
Doch trotzdem - auch ohne das round() - kommt außer bei 1.0 und 2.0 immer 1.100000000000000001 oder 1.300000000000000001.

Auch mit nem randint() bin ich nicht weitergekommen...

Was soll der Müll :S?
Ich brauche 1 Kommastelle, wenn es mehr sind, funktioniert es nicht mehr ^^

Könnt ihr mir da helfen?

~ Chris

Verfasst: Samstag 16. August 2008, 22:13
von Nocta
Hi.

Code: Alles auswählen

>>> print speed
[1.3999999999999999, 1.8]
>>> print speed[0]
1.4
Ich denke mal die Begründung ist die, dass man mit dem Binärsystem einige Zahlen nicht korrekt darstellen kann (was aber bei normalen Berechnungen nicht weiter schlimm sein dürfte, bei der geringen Abweichung). Wie man an dem "Code" den ich gepostet hab, sieht, ist's ja auch eigentlich 1.4 (mit einer geringen Abweichung eben) ;)
Ich hoffe mal dass das die richtige Erklärung für dieses Problem ist, ich hab das selbst auch nur mal hier im Forum gelesen und hab mir darüber noch nicht so die Gedanken gemacht.

Verfasst: Samstag 16. August 2008, 22:19
von BlackJack
@Chrisber: Lesen und verstehen: http://docs.python.org/tut/node16.html

Verfasst: Samstag 16. August 2008, 22:30
von theliquidwave
Omg >_>
Danke :oops:

~ Chris

Verfasst: Sonntag 17. August 2008, 07:09
von numerix
Vielleicht sollte man noch anmerken, dass die Auswahl aus der manuell erzeugten Liste mit Werten hier auch nicht das Gelbe vom Ei ist

Eine Variante wäre:

Code: Alles auswählen

from random import randrange
speed = 0.1*randrange(10,21)

Verfasst: Sonntag 17. August 2008, 11:58
von CM
numerix hat geschrieben:Vielleicht sollte man noch anmerken, dass die Auswahl aus der manuell erzeugten Liste mit Werten hier auch nicht das Gelbe vom Ei ist
Warum?

Außerdem erlaubt sample() auch mehrere Rückgabewerte auf einmal, wordurch ausgeschlossen wäre, dass speed[0] == speed[1] ist:

Code: Alles auswählen

sample([1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0], 2)
edit: Inwieweit das sinnvoll ist, hängt natürlich vom Programm ab.

Gruß,
Christian

Verfasst: Sonntag 17. August 2008, 14:10
von numerix
CM hat geschrieben:
numerix hat geschrieben:Vielleicht sollte man noch anmerken, dass die Auswahl aus der manuell erzeugten Liste mit Werten hier auch nicht das Gelbe vom Ei ist
Warum?
Für meinen Geschmack ist es einfach unschick, eine Liste von Zahlenwerten per Hand zu notieren, wenn ich das Programm - ohne großen Aufwand - dazu bringen kann, mir diese Zahlen zu erzeugen.

Verfasst: Montag 18. August 2008, 08:57
von sma
Statt die Liste per Hand zu notieren, könnte man `range` benutzen - leider funktioniert das nicht mit floats, sodass man etwas umständlicher `[x / 10.0 for x in range(10, 21, 1)]` benutzen muss.

Die Ausgabe zeigt dann auch sehr schön die Ungenauigkeitsprobleme mit floats und daher mein abschließender Tipp: Lieber überall im Programm mit dem 10-fachen, also den Ganzzahlen arbeiten und erst am Schluss für die Anzeige teilen und runden. Alternativ kann man auch Decimal-Objekte (nach einem `import decimal`) benutzen oder Fraction-Objekte (nach einem `import fractions` für Python 2.6 oder 3.0 oder nachdem man sich so eine Klasse selbst gebaut hat).

Stefan

Verfasst: Montag 18. August 2008, 12:08
von CM
Es geht auch:

Code: Alles auswählen

from numpy import linspace
from random import sample
sample(linspace(1, 2, 11), 2)
Oder man generiert die Reihe mit einer LC. Ginge auch als Einzeiler ... s.o.

Ich hatte schon gedacht, dass es irgendeinen Grund gibt, der besagt, dass die Zahlen nicht genauso zufällig sind, wie mit randrange (was mich erstaunt hätte, aber manchmal interpretiert man halt die blödesten Dinge in einen Post).

Gruß,
Christian

PS Der Aufwand orientiert sich halt daran, wie häufig so eine Funktion aufgerufen wird. U. U. ist es wohl besser die Liste einmal zu generieren und ansonsten 'sample()' zu übergeben.