Этот вопрос: Как создать случайный 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;
}