To pytanie: How to generate a random BigInteger opisuje sposób osiągnięcia tej samej semantyki co Random.nextInt (int n) w przypadku BigIntegers.Jak utworzyć losowy BigDecimal w Javie?
Chciałbym zrobić to samo dla BigDecimal i Random.nextDouble().
Jedna z odpowiedzi w powyższym pytaniu sugeruje utworzenie losowego BigInteger, a następnie utworzenie BigDouble z niego z losową skalą. Bardzo szybki eksperyment pokazuje, że jest to bardzo zły pomysł :)
Moja intuicja jest to, że za pomocą tej metody wymagałoby całkowitą być skalowane przez coś podobnego
n-log10(R)
, gdzie n oznacza liczbę cyfr precyzji wymaganych w wyjście i R jest losowym BigIntegerem. Powinno to pozwolić na obecność prawidłowej liczby cyfr, aby (na przykład) 1 -> 10^-64 i 10^64 -> 1.
Wartość skalowania również musi być wybrana poprawnie, aby wynik spadł w zakresie [0,1].
Czy ktoś to zrobił wcześniej i czy wie, czy wyniki są prawidłowo dystrybuowane? Czy istnieje lepszy sposób na osiągnięcie tego?
EDYTOWANIE: Dzięki @biziclop za poprawienie mojego rozumienia argumentu skali. Powyższe nie jest konieczne, stały współczynnik skali ma pożądany efekt.
do późniejszego wykorzystania, mój (kod najwyraźniej pracuje) wynosi:
private static BigDecimal newRandomBigDecimal(Random r, int precision) {
BigInteger n = BigInteger.TEN.pow(precision);
return new BigDecimal(newRandomBigInteger(n, r), precision);
}
private static BigInteger newRandomBigInteger(BigInteger n, Random rnd) {
BigInteger r;
do {
r = new BigInteger(n.bitLength(), rnd);
} while (r.compareTo(n) >= 0);
return r;
}
To była część "oryginalnej skali", która była błędna. Ta metoda powinna być w porządku. – DJClayworth
Możesz utworzyć jednolity BigInteger mniej niż 10^N kupić, tworząc wiele liczb całkowitych, które są [0, 10^m) i łącząc je. –
Racja, ale jest odpowiednie pytanie z ładną odpowiedzią powiązaną w pierwszym zdaniu tego pytania. Twoja propozycja może również dobrze działać, szczególnie przy m = 9, więc random może być użyty random.nextInt(). – maaartinus