-
Grenze für Zufallszahlenerzeugung
Wir nutzen folgendes Statement zur Erzeugung einer Zufallszahl:
Exec SQL Set :ZufallsZ2 = Rand();
wobei ZuFallsZ2 als 15,7 Feld definiert ist.
Man denkt es würden maximal 9999999 verschiedene Zahlen erzeugt werden, tatsächlich sind es auch bei 9999999 Durchläufen nur 32766 verschiedene Zahlen.
Wo ist der Denkfehler/Programmfehler?
Die Zufallszahl wird als Index eines Lagerplatzes genutzt.
-
Ich weiß nicht, ob meine Antwort das Problem löst, aber:
Rand() liefert keine Zahl, die größer als 1 ist. Es wird immer nur eine Zahl (Genauigkeit double float) zwischen 0 und 1 geliefert. Um daraus eine für dich brauchbare Zufallszahl zu bekommen, musst du die Zahl mit deinem maximalen Wertebereich multiplizieren.
Z.B.: Du willst einen Würfelwurf abbilden:
Dann wäre deine Zufallszahl int(Rand() * 6) + 1.
Wenn du deine 9.999.999 Millionen Lagerplätze abbilden wolltest, müsstest du int(Rand() * 9999999 ) + 1 verwenden. Das "+ 1" ist dafür, dass du keine 0 erhältst und dass dein maximaler Wert auch erreicht wird.
Dein Ergebnisfeld sollte in deinem Fall übrigens ganzzahlig sein!
Also Zufallszahl nicht als 15,7 sondern als 8,0 deklarieren!
Dieter
-
EXEC SQL SET :ZZAHL = (int(Rand() * 9999999 ) + 1); wobei ZZAHL 7,0
Es werden 32767 verschiedene Zahlen produziert.
Wir haben das Programm 2mal durchlaufen lassen. Die Zahlen sind identisch.
-
Sorry, mein Beispielprogramm, das hier eben noch stand war Quatsch. Ich lösche den Code aus diesem Text.
-
Du hast Recht. Mein Beispielprogramm kommt auch immer nur auf ca. 32000 unterschiedliche Zahlen.
Code:
dcl-s zahlen packed(8) dim(100000);
dcl-s zahl packed(8);
dcl-s elem packed(8);
dcl-s i packed(8);
clear zahlen;
for i=1 to 200000;
exec sql set :zahl = (int(Rand() * 9999999 ) + 1);
if %lookup(zahl : zahlen) = 0;
elem += 1;
zahlen(elem) = zahl;
endif;
endfor;
dsply %char(elem);
*inlr = *on
-
Ich habe es eben mal mit SQL probiert. Dabei kommen tatsächlich nur 32768 unterschiedliche Zahlen raus. Obwohl die Nachkommastellen von Rank() sehr zahlreich sind, sind viele Daten gleich.
Hier mein Test (mit eine Tabelle, die mehr als 3,7 Millionen Datensätze enthält:
-- Aus folgender Abfrage kommt immer 32768 raus:
with daten as (
select rand() as zahl from mytable limit 1000000)
select count(distinct zahl) from daten
;
-- Hier mal ein paar Beispieldaten aus folgender Abfrage:
with daten as (
select rand() as zahl from mytable limit 1000000)
select zahl from daten order by zahl
;
0.00924710837122715
0.00924710837122715
0.00924710837122715
0.009277626880703146
0.009277626880703146
0.009277626880703146
0.009277626880703146
0.009277626880703146
0.009277626880703146
Da müsste man IBM mal fragen, was das soll.
-
So ganz Random sind die Zahlen wohl nicht.
Was spircht gegen die RRN als Index?
-
Zufallszahl als Index für eine Lagerplatz?
Da finde ich persönlich eine Identity-Column als INT oder BIGINT, die sich ständig hochzählt, für geeigneter.
Neben der Anforderung eigentlich eine Platz-Id zu haben á la 'Lager-Gang-Regal-Block-Ebene-Platz'.
Zufall sollte in der Logistik eher nicht vorkommen;-).
-
Zitat von Fuerchau
Zufall sollte in der Logistik eher nicht vorkommen;-).
https://www.zufall.de/
...sorry- konnte ich mir nicht verkneifen ;-)
-
... habe mal auf die Schnelle ein create table as (select rand() unrand from aLargeTable) with data gemacht. Mit analogen Resultaten. Da sind alle Faktoren raus, über die man nachdenken könnte.
=> die Funlktion rand() ist in DB2/400 völliger Murks!
Wie das für Lagerplätze funzen soll, ierschließt sich mir allerdings nicht. Selbst eine korrekte rand() Funktion ist nicht frei von Kollisionen und wo soll dann der Kram hin?
D*B
-
Neben der IDENTITY gäbe es auch SEQUENCE
CREATE SEQUENCE MySeq
START WITH 1
INCREMENT BY 1
MAXVALUE 10000
CYCLE
VALUES (NEXT VALUE FOR MySeq)
-
SEQUENCE war vor Identity.
Eine SEQUENCE benötigt eine zusätzloche DTAARA, während Identity innerhalb der Tabelle abgebildet wird.
Andererseits kann SEQUENCE auch für mehrere Tabellen verwendet werden.
Im Gegensatz zu SEQUENCE ist Identity lückenlos, wenn man sie nicht manipuliert.
Bei SEQUENCE können aus Performancegründen mehrere Werte auf 1x abgerufen und gecached werden (Default 20). Wenn dann weniger Inserts laufen, ist der Rest dann enfach weg.
Außerdem kann man bei Identity im Insert die Spalte einfach weglassen, bei SEQUENCE benötigt man die Funktion.
Similar Threads
-
By Joe in forum NEWSboard Programmierung
Antworten: 8
Letzter Beitrag: 29-03-11, 13:23
-
By KingofKning in forum IBM i Hauptforum
Antworten: 1
Letzter Beitrag: 08-03-10, 09:23
-
By schatte in forum IBM i Hauptforum
Antworten: 2
Letzter Beitrag: 04-10-06, 15:22
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks