Этот вопрос: Как сгенерировать случайный BigInteger описывает способ достижения той же семантики, что и Random.nextInt (int n) для BigIntegers.
Я хотел бы сделать то же самое для BigDecimal и Random.nextDouble ().
Один из ответов в приведенном выше вопросе предлагает создать случайное BigInteger, а затем создать из него BigDouble со случайным масштабом. Очень быстрый эксперимент показывает, что это очень плохая идея: )
Моя интуиция подсказывает, что использование этого метода потребует масштабирования целого числа на что-то вроде n-log10 (R)
, где n - количество цифр точности, требуемое на выходе, а R - случайный BigInteger. Это должно позволить присутствовать правильное количество цифр, чтобы (например) 1 -> 10 ^ -64 и 10 ^ 64 -> 1.
Значение масштабирования также должно быть выбрано правильно, чтобы результат попадал в диапазон [0,1].
Кто-нибудь делал это раньше, и знают ли они, правильно ли распределяются результаты? Есть ли лучший способ добиться этого?
EDIT: Спасибо @biziclop за исправление моего понимания аргумента масштаба. Вышеупомянутое не обязательно, постоянный масштабный коэффициент дает желаемый эффект.
Для дальнейшего использования мой (очевидно рабочий код):
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;
}