He hecho tal experimento: hice 10 millones de números aleatorios de C y C#. Y luego contó cuántas veces se establece cada bit de 15 bits en entero aleatorio. (Elegí 15 bits porque C solo admite números enteros aleatorios hasta 0x7fff
).Bits más probables en entero al azar
lo que tengo es la siguiente:
tengo dos preguntas:
Por qué hay 3 bits más probables? En
C
son más probables los bits de caso8,10,12
. Y enC#
bits6,8,11
son los más probables.También parece que C# bits más probables es mayormente desplazado por 2 posiciones y luego comparado con C bits más probables. Por qué es esto ? Porque C# usa otra constante RAND_MAX o qué?
Mi código de prueba para
C
:
void accumulateResults(int random, int bitSet[15]) {
int i;
int isBitSet;
for (i=0; i < 15; i++) {
isBitSet = ((random & (1<<i)) != 0);
bitSet[i] += isBitSet;
}
}
int main() {
int i;
int bitSet[15] = {0};
int times = 10000000;
srand(0);
for (i=0; i < times; i++) {
accumulateResults(rand(), bitSet);
}
for (i=0; i < 15; i++) {
printf("%d : %d\n", i , bitSet[i]);
}
system("pause");
return 0;
}
Y Código de ensayo para C#
:
static void accumulateResults(int random, int[] bitSet)
{
int i;
int isBitSet;
for (i = 0; i < 15; i++)
{
isBitSet = ((random & (1 << i)) != 0) ? 1 : 0;
bitSet[i] += isBitSet;
}
}
static void Main(string[] args)
{
int i;
int[] bitSet = new int[15];
int times = 10000000;
Random r = new Random();
for (i = 0; i < times; i++)
{
accumulateResults(r.Next(), bitSet);
}
for (i = 0; i < 15; i++)
{
Console.WriteLine("{0} : {1}", i, bitSet[i]);
}
Console.ReadKey();
}
Muy gracias !! Por cierto, el sistema operativo es Windows 7, la arquitectura de 64 bits & Visual Studio 2010.
EDITAR
Muy gracias a @ David Heffernan. Cometí varios errores aquí:
- La semilla en los programas C y C# era diferente (C estaba usando cero y C# - hora actual).
- No intenté experimentar con diferentes valores de la variable
Times
para investigar la reproducibilidad de los resultados.
Esto es lo que tengo cuando se analiza cómo probabilidad de que la primera bit se establece depende del número de veces al azar() se llama:
Así como muchos notado - Los resultados no son reproducibles y no deben ser tomado en serio. (Excepto como una forma de confirmación de que C/C# PRNG es lo suficientemente bueno :-)).
No puedo recordar mucho de mis clases de estadística en la escuela, pero debe averiguar si los valores atípicos son estadísticamente significativo o simplemente un resultado de error aleatorio. Nunca obtendrás una distribución perfecta. –
¿Estos resultados son reproducibles? Eso me sorprendería. Si ejecuta la misma prueba varias veces, sospecho que en las siguientes ejecuciones, saldrán diferentes bits "más probable" y "menos probable". – abelenky
No tengo dudas de que son reproducibles. 'rand' normalmente se implementa con una congruencia lineal PRNG, que tiene propiedades estadísticas ridículamente malas. Su mejor esperanza de obtener resultados razonables de 'rand' es usar solo un bit (el bit alto) de cada llamada, y llamarlo repetidamente ... –