Esta pregunta: How to generate a random BigInteger describe una forma de lograr la misma semántica que Random.nextInt (int n) para BigIntegers.¿Cómo puedo crear un BigDecimal aleatorio en Java?
Me gustaría hacer lo mismo para BigDecimal y Random.nextDouble().
Una respuesta en la pregunta anterior sugiere crear un BigInteger aleatorio y luego crear un BigDouble a partir de él con una escala aleatoria. Un experimento muy rápido muestra que esta es una muy mala idea :)
Mi intuición es que usar este método requeriría que el entero fuera escalado por algo como
n-log10(R)
, donde n es el número de dígitos de precisión requeridos en el salida y R es el BigInteger aleatorio. Esto debería permitir que el número correcto de dígitos esté presente para que (por ejemplo) 1 -> 10^-64 y 10^64 -> 1.
El valor de escala también debe elegirse correctamente para que el resultado caiga. en el rango [0,1].
¿Alguien ha hecho esto antes, y saben si los resultados están distribuidos correctamente? ¿Hay una mejor manera de lograr esto?
EDIT: Gracias a @biziclop por corregir mi comprensión del argumento de la escala. Lo anterior no es necesario, un factor de escala constante tiene el efecto deseado.
Para tener una referencia más tarde, mi (código aparentemente de trabajo) es:
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;
}
Era la parte de "escala aleatoria" de la respuesta original incorrecta. Este método debería estar bien. – DJClayworth
Puede crear un BigInteger uniforme de menos de 10^N buy creando muchos enteros que son [0, 10^m) y combinándolos. –
Correcto, pero hay una pregunta correspondiente con una buena respuesta vinculada en la primera oración de esta pregunta. Su propuesta también puede funcionar bien, especialmente con m = 9, por lo que se puede usar random.nextInt(). – maaartinus