Zufallszahl mit 1 Kommastelle

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

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
Grüßle.
Nocta
User
Beiträge: 290
Registriert: Freitag 22. Juni 2007, 14:13

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.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Omg >_>
Danke :oops:

~ Chris
Grüßle.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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.
Antworten