Zufallswert zwischen 0.0 und 1.0 (inklusive) sehr feingranular

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?

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.

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:

1 Like