![]() |
Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo,
Ich benutze diese beiden Funktionen um Zufalls-Gleitkommazahlen in einem bestimmten Bereich zu bekommen.
Delphi-Quellcode:
Mit diesen Funktionen bekomme ich Gleitkommazahlen immer mit 2 Nachkommastellen, ich würde aber gerne auch die Nachkommastellen durch den Zufallsgenerator laufen lassen, so dass ich immer Nachkommastellen von 0 bis 8 bekomme.
function iZufallsZahlen(Von, Bis: Integer): integer;
begin Result:= RandomRange(Von, Bis+1); end; function dZufallsZahlen(Von, Bis: Integer): Double; begin Result:= iZufallsZahlen(Von*100, bis*100)/100; end; Hat einer eine Idee, wie man das am besten realisieren kann? Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit Zufälligen Nachkommastellen
Delphi-Quellcode:
function Random2(digitCount: Integer): Double;
var i: Integer; offset: Double; begin Result := 0; offset := 0.1; for i := 1 to digitCount do begin Result := Result + Random(9) * offset; offset := offset * 0.1; end; end; |
Re: Zufallsgleitkommazahlen mit Zufälligen Nachkommastellen
Ich weiß nicht, ob ich genau verstanden habe, was du willst, aber vllt. ist es das: (?)
Delphi-Quellcode:
MfG,
function dZufallsZahlen(Von, Bis: Integer): Double;
begin Result:= von+random*(bis-von); end; Bug |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Delphi-Quellcode:
function dZufallsZahlen(Von, Bis: Integer; Stellen:byte): Double;
var K:cardinal; begin K:=trunc(power(10, Stellen)); Result:= (Von*K + random((bis-von)*K)) / K; end; |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Ich lese die Anforderung als Random2.ToString ~ [0-8]+ - dann würde der normale Generator eher versagen, egal wie er gewrapt wird.
|
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo,
Dank für die Antworten. @Bug: Die Gleitkommazufallszahlen in Deiner Function leistet meine Function auch. Ich würde gerne auch die Nachkommastellen durch den Zufallsgenerator bestimmen lassen. Das Ergebnis sollte dann wie folgt aussehen: 100,01234 99,2 -0,0004 usw. @Dax: Mit Deiner Funktion kommen auch immer die gleiche Anzahl an Stellen raus. Ich kann jetzt nicht so richtig feststellen, was der unterschied zu meiner Function ist. @omata: Die Function leistet das gleiche wie meine Function außer das ich die Stellenzahl direkt vorgegeben habe durch die Division durch 100. Ich muss die Frage präziser stellen. Die Function dZufallsZahlen kann Gleitkommazufallszahlen in einem Bereich von bis generieren. z.B.: von -100 bis 100 Ich möchte die Gleitkommazufallszahlen aber zusätzlich mit unterschiedlicher Kommastelle erstellen. Wie die Funktion jetzt erstellt worden ist kommen immer 2 Nachkommastellen. Die Zahlen sollen also zwischen von und bis liegen und zusätzlich verschiede Nachkommastellen haben. Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Zitat:
Delphi-Quellcode:
function dZufallsZahlen(Von, Bis: Integer; Stellen:byte): Double;
var K:cardinal; begin K:=trunc(power(10, Stellen)); Result:= iZufallsZahlen(Von, Bis) + random(K) / K; end; |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo,
ich glaube, dass ich eine Lösung gefunden habe.
Delphi-Quellcode:
Vielleicht kann das einer von Euch mal überprüfen, ob man das so machen kann.
function iZufallsZahlen(Von, Bis: Integer): integer;
begin Result:= RandomRange(Von, Bis+1); end; function dZufallsZahlen(Von, Bis: Integer): Double; const ArrKommaStellen : Array [0..7]of Integer =(1, 10, 100, 1000, 10000, 100000, 1000000, 10000000); var KommaStellen: Integer; begin KommaStellen:= RandomFrom(ArrKommaStellen); Result:= iZufallsZahlen(Von*KommaStellen, bis*KommaStellen)/KommaStellen; end; @Omata: Ich werde Deine Lösung auch noch mal prüfen. Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo Omata,
die Werte sind aber nicht immer in den von bis Bereich. Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Einfacher:
Delphi-Quellcode:
Dennoch ist hierbei niemals sicher, dass die resultierenden Zahlen auch wirklich Log10(KommaStellen) Nachkommastellen hat, was an der internen Darstellung von Fließkommazahlen liegt. Das ist ein systemisches Problem, dass du nur über einen Festkommadatentyp lösen kannst. Zudem musst du aufpassen, weil ein Double mehr Nachkommastellen haben kann, als ein Integer Stellen insgesamt. Das heisst, dass du dir mit mehr als 8 Nachkommastellen sehr wahrscheinlich einen Integer-Überlauf in obiger Funktion einhandelst.
function dZufallsZahlen(Von, Bis: Integer): Double;
var KommaStellen: Integer; begin KommaStellen := Power(10, random(8))*10; Result := iZufallsZahlen(Von*KommaStellen, bis*KommaStellen)/KommaStellen; end; Um das zu beseitigen würde ich es dann so machen:
Delphi-Quellcode:
Die Ungenauigkeit der Floats bleibt jedoch, insbesondere bei sehr großen Zahlen wird sich das hier bemerkbar machen. Ebenso dürfte es bei 15 Nachkommastellen zu erheblichen Rechenfehlern kommen, da ja eine Zahl aus dem Bereich (Von; Bis) mit 1000000000000000 multipliziert wird, und damit dann die signifikanten Stellen von Double überschritten werden, sobald die Zahl >10 ist.
function dZufallsZahlen(Von, Bis: Integer): Double;
var KommaStellen: Double; begin KommaStellen := Power(10, random(15))*10; Result := (Trunc(Von + random*(Bis-Von))*KommaStellen)/KommaStellen; end; D.h. du müsstest vorher einplanen, wie viele Stellen deine Zahlen vor dem Komma haben können sollen, und entsprechend 15 minus dieser Anzahl an Nachkommastellen zulassen. (15 weil Double 15-16 signifikante Stellen im Dezimalsystem hat, womit man mit 15 auf der sicheren Seite ist.) Alternativ kannst du aber auch folgendes machen:
Delphi-Quellcode:
Dabei wird einfach eine Zufallszahl mit zufällig vielen Nachkommastellen (meistens wohl "alle") erzeugt, und zusätzlich ein Zufallsinteger zurückgegeben, der die Anzahl der bei der Darstellung der Zahl als String zu verwendenden Nachkommastellen angibt. Um ggf. Nullen an das Ende anzufügen um eine feste Länge der Zahl zu erreichen, würde ich dann auf Stringoperationen zurückgreifen: Einfach '0' anhängen bis der String die richtige Länge hat. Damit brauchst du dich nicht mehr um die Ungenauigkeiten von Floats zu scheren, dafür taugt es aber halt auch nur, wenn es dir explizit darum geht diese Zahlen als String auszugeben. Wenn es für eine weitere Berechnung erheblich ist wie viele Nachkommastellen eine Zahl hat, dann kommst du um Fixed-Point Arithmetik nicht herum.
function dZufallsZahlen(Von, Bis: Integer; var KommaStellen: Integer): Double;
begin KommaStellen := random(16); Result := Von + random*(Bis-Von); end; Fazit: Da man bei der trunc(Muliplikation)Divisions-Methode sehr schnell die jeweiligen Wertebereiche überschreitet, und man eben mit der internen Darstellung von Floats so seine Last hat wenn es auf die Genauigkeit so an kommt, wäre der 3. Vorschlag der einzige der sicher genug arbeitet, oder aber wenn mit den Werten in dieser Genauigkeit (nämlich exakte Genauigkeit) weiter gerechnet werden soll, kommt man nur noch mit Festkommazahlen ans Ziel. Alles andere wäre Rumgehackel und bestenfalls ein "dirty trick", aber nichts zum vorm Chef damit glänzen ;) |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Wenn man die Random() Funktion ohne Parameter aufruft, bekommt man Zufallszahlen zwischen 0.0 und 1.0.
Random() ist überladen - siehe OH. Man muss diesen Wertebereich nur noch verschieben und skalieren. |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo,
@sx2008: Das die Random() Function überladen ist, ist mir bekannt, allerdings wenn man einen Werte-Bereich angibt werden nur Interger-Zahlen zurückgegeben. @Medium: Danke erst mal für ausführliche Informationen. Die erste Funktion müsste nur geändert werden um die Nachkomma-Stellen als Integer zu bekommen. Geändert:
Delphi-Quellcode:
Nach einem kurzen Test funktioniert sie wunschgemäß.
function dZufallsZahlen(Von, Bis: Integer): Double;
var KommaStellen: Integer; begin KommaStellen := trunc(Power(10, random(8))*10); Result := iZufallsZahlen(Von*KommaStellen, bis*KommaStellen)/KommaStellen; end; Es sollen Zahlen zwischen -1000 und 100000 generiert werden, da sollte der Werte-Bereich noch funktionieren. Der String der erstellt wird von der Zufallszahl soll unterschiedliche Länge haben und nicht mit Nullen aufgefüllt werden. Zitat:
Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Zitat:
Delphi-Quellcode:
function dZufallsZahl(Von, Bis: Double): Double;
begin Result := (Bis-Von)*Random + Von; end; |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo sx2008,
die Zufallszahlen waren nicht das Problem sondern, die variablen Kommastellen. Prüfe mal Deine Funktion mit den Werten: von: 0.00001 bis: 0.00002 dann wirst Du sehen das der Bereich nicht mehr eingehalten wird. Medium hat die Erklärung dafür gegeben. Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Zitat:
Zwischen 0 und 1 gibt es genau 8 Werte, die genau eine Nachkommastelle haben. Es gibt 90 Werte, die 2 NKs haben, es gibt 900 Werte mit 3 NKs,... Ein echte Zufallszahl wird mit sehr hoher Wahrscheinlichkeit sehr viele Nachkommastellen haben. Zwischen zwei Zahlen, egal wie eng sie beieinander liegen, sind unendlich viele Zahlen dazwischen. Man darf Zufallszahlen auf eine bestimmte Anzahl Nachkommastellen runden und es bleiben immer noch gleichverteilte Zufallszahlen. Wenn man aber aber wie oben versucht die NKs so zu beeinflussen, dass sie zwischen 0 und 8 liegen, dann hat das mathematisch nicht mehr viel mit Zufallszahlen zu tun. Insbesondere ist die Gleichverteilung gestört. |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo sx2008,
im Grunde genommen werden die Zufallszahlen ab einer zufällig gewählten Stelle abgeschnitten, die Zufallszahlen werden ja bei der Entstehung nicht beeinflusst. Die Zahlen sollen zwischen -1000 und 100000 liegen. Die gleichmäßige Wahrscheinlichkeit ist nicht so wichtig, wobei auch bei den Nachkommastellen eine zufällige Verteilung besteht. Ich bin sowieso der Meinung, dass man mit einem Rechner keine echten Zufallszahlen generieren kann. Bis bald Chemiker |
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Zitat:
|
Re: Zufallsgleitkommazahlen mit zufälligen Nachkommastellen
Hallo alzaimar,
die Zufallszahlen werden für eine Simulation gebraucht. Random() ist nicht für Kryptographie geeignet, laut der Delphi-Hilfe. Zudem würden meine bescheiden Mathematischen Kenntnisse für Kryptographie nicht ausreichen. Bis bald Chemiker |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz