Zufallswert zwischen 0.0 und 1.0 (inklusive) sehr feingranular


#1

Hallo, beim Erstellen von Zufallswelten ist mir aufgefallen, dass ich oft Wege mit 100 bis 200 % eines bestimmten Werts brauche.
Random: Die 1.0 (in diesem Fall 200 %) soll aber genauso häufig wie die 0.999… erstellt werden:

        Random r = new Random(3);
        // 2 exklusive, sehr feingranular
        System.out.println( 12345 * (1 + r.nextDouble()) );
        // 2 inklusive, nicht sehr feingranular
        System.out.println( 12345 * (100 + r.nextInt(101)) / 100.0 );
        // 2 inklusive, 1.99, 1.98, 1.97 usw. haben höhere Wahrscheinlichkeit...
        System.out.println( 12345 * Math.round(100 + 100 * r.nextDouble()) / 100.0 );

Könntet ihr das lösen?


#2

Das zweite ist eine sinnvolle Option, unter der Annahme, dass die Verteilung der Ganzzahlen vernünftig ist, und man statt der 100 Schritte auch 100000 verwenden kann.


A*-Implementierung ist fehlerhaft
#3

Also man hat bei Doubles 52 Mantissenbits, das bedeutet, 2^52 Bitkombinationen pro Exponent. Ein Wechsel des Exponenten findet also sicher nach (2^52)+1 Kombinationen statt:

final double MAX = Math.pow(2.0, 52.0)+1.0; double rnd = (Math.random() * (MAX + 1.0))/MAX; // hier nochmal + 1, weil eine Grenze // von random exclusiv istSoviel zur Theorie. Ob das wirklich alle Werte zwischen 0 und 1 in Java ergibt, kannst du ja mal selber testen.

final double MAX = Math.pow(2.0, 52.0) + 1.0; double rnd = -1; for(long n = 0; n <= MAX; n++) { double t = n / MAX; if(t == rnd) { System.out.print("doublette"); break; } System.out.println(t); rnd = t; }

Edit: “n < MAX +1” sah längst nicht so gut aus wie “n<= MAX”. :smiley: