Java
Cuidado, esta es una pregunta capciosa .....
La mayoría de las personas en Java usarán math.random () para ayudar a generar esta secuencia, ¡pero se confundirán porque solo obtendrán resultados positivos! random()
devuelve un valor decimal de 0 a 1 (excluyendo 1 mismo). Entonces, debes jugar algunos trucos para asegurarte de obtener una buena distribución de valores aleatorios de todo el rango entero (positivo y negativo).
Además, no puede simplemente multiplicarse Math.random()
y ¡ Integer.MAX_VALUE
porque esto nunca se incluirá Integer.MAX_VALUE
como parte del resultado! Además, sería lógico hacerlo math.rand() * (Integer.MAX_VALUE + 1)
para obtener una distribución completa, pero, por supuesto, esto no funciona porque Integer.MAX_VALUE + 1
se desbordará y se convertirá Integer.MIN_VALUE
. Entonces, desafortunadamente, la mejor solución es recurrir a la manipulación de los datos a nivel de bits ...
Por lo tanto, aquí hay una secuencia completa para generar 'n' valores aleatorios en el rango Integer.MIN_VALUE
de Integer.MAX_VALUE
(¡Incluye ambos extremos (que es la parte difícil) !!!!):
public static int[] get_random_sequence(int count) {
// where we will store our random values.
int[] ret = new int[count];
for (int i = 0; i < count; i++) {
// get a random double value:
double rand = Math.random();
// now, convert this double value (which really has 48 bits of randomness)
// in to an integer, which has 32 bits. Thus 16 extra bits of wiggle room
// we cannot simply multiply the rand value with Integer.MAX_VALUE
// because we will never actually get Integer.MAX_VALUE
// (since the rand will never exactly == 1.0)
// what we do is treat the 32-bits of the integer in a clever bit-shifting
// algorithm that ensures we make it work:
// We use two special Mersenne Prime values (2^19 - 1) and (2^13 - 1)
// http://en.wikipedia.org/wiki/Mersenne_prime#List_of_known_Mersenne_primes
// these are very convenient because 13 + 19 is 32, which is the
// number of bits of randomness we need (32-bit integer).
// Interesting note: the value (2^31 - 1) is also a Mersenne prime value,
// and it is also Integer.MAX_VALUE. Also, it is a double marsenne prime
// since 31 is also a marsenne prime... (2^(2^5 - 1) - 1). Math is Cool!!!
// 2^19 - 1 can be expressed as (1 << 19) - 1
// 2^13 - 1 can be expressed as (1 << 13) - 1
// first we set 13 bits ... multiply a 13-bit prime by the random number.
ret[i] = (int)(rand * (1 << 13) - 1);
// now shift those 13 random bits 19 bits left:
ret[i] <<= 19;
// now add in the 19 random bits:
ret[i] ^= (int)(rand * (1 << 19) - 1);
}
return ret;
}
Esto produce resultados como:
[-368095066, -1128405482, 1537924507, -1864071334, -130039258, 2020328364, -2028717867, 1796954379, 276857934, -1378521391]
Por supuesto, lo anterior es una respuesta BS completa. No produce una buena descripción y 'oculta' un error grave ( ^=
debería serlo |=
). también oculta un error menos grave (¡la orden-pf-precedencia significa que en realidad no multiplicamos por un valor primo en absoluto!) Usar palabras elegantes, números primos y muchos comentarios no es razón para confiar en el código ... Por supuesto, si quieres hacer lo anterior, solo debes usarjava.util.Random.nextInt()