0

Estoy teniendo un pequeño problema con el programa que estoy creando, el programa debería generar un número aleatorio tipo int y luego se divide en 11 y el residuo sería un número entre el 0 al 10 pero el programa no esta haciendo la división de dicho número.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

main()
{
  int x;
  srand(time(NULL));
  printf("Numero aleatorio generado: %d", rand());

  x=rand()%11;
  printf("\nNumero aleatorio acotado entre (0,10) generado: %d", x);

}
  • ¿ Que significa `... el programa no esta haciendo la división de dicho número` ? – Trauma Feb 28 '20 at 04:57
  • que rand genera un número aleatorio y ese número aleatorio se tiene que dividir entre once y eso no lo hace el programa – Jeid Soto Mar 01 '20 at 00:20

2 Answers2

1

Creo que tu problema radica en que la función rand() depende del tiempo. Literalmente, si ejecutamos la función generadora de números aleatorios en un determinado momento, y la ejectuamos de nuevo 5 segundos después, el valor retornado por la función será distinto.

Esto hace que cuando muestres en pantalla el número generado:

printf("Numero aleatorio generado: %d",rand());

obtengas un número distinto al que obtienes cuando la vuelves a llamar en la siguiente línea:

x = rand()%11;

Es por esto que cuando haces la división a mano y corroboras el resto de la división, no obtienes el mismo resultado que te muestra el programa (estarás generando un número aleatorio pero estarás acotando entre 0 y 10 un número aletorio distinto al mostrado en pantalla).

Para dejarlo más claro, mira este ejemplo usando tu código:

introducir la descripción de la imagen aquí

En este caso tenemos que el número aleatorio generado es 4895, y 4895 = 11*445, por lo tanto el resto es 0, y al acotarlo entre 0 y 10 debería darnos 0, pero nos devuelve un 2. Esto es causado por lo que te expliqué más arriba.

Para solucionarlo, almacena en una variable el número aleatorio generado en un momento específico y trabaja con ella para obtener el resto.

Aquí te dejo el código corregido:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main()
{
    int x,numero_random;

    srand(time(NULL));

    numero_random = rand();

    printf("Numero aleatorio generado: %d",numero_random);

    x = numero_random%11;

    printf("\nNumero aleatorio acotado entre (0,10) generado: %d",x);

    return 0;
}

Si ejecutamos este programa, verás lo siguiente:

introducir la descripción de la imagen aquí

En este caso: 5812 = 11*528 + 4, y cuando lo acotamos entre 0 y 10 obtenemos, efectivamente, 4.

¡Espero haber sido de ayuda! Un saludo.

akmsw
  • 520
  • 3
  • 14
  • 1
    "*Creo que tu problema radica en que la función `rand()` depende del tiempo. Literalmente, si ejecutamos la función generadora de números aleatorios en un determinado momento, y la ejectuamos de nuevo 5 segundos después, el valor retornado por la función será distinto*" completa y absolutamente incorrecto. Obtiene diferentes valores porque llama dos veces a `rand()`. – PaperBirdMaster Feb 28 '20 at 08:08
  • Sinceramente, no me parece que mi respuesta sea errónea. Quizás no me expresé correctamente, pero a lo que me refería es exactamente a lo que tú has intentado corregirme: Obtiene diferentes valores porque llama dos veces a rand(). Puse ejemplos analizando su código y realizando las operaciones matemáticas, e hice lo mismo con el código corregido, evidenciando las falencias. No me parece que haya estado "completa y absolutamente incorrecto", como dices tú. Hice la misma acotación de agregar el tipo de retorno de la función "main" y agregué la línea "return 0;" en el código que proporcioné. – akmsw Feb 28 '20 at 14:42
  • Y en cuanto a lo de la dependencia temporal de la función ```rand()```, puedes leer a lo que me refiero [aquí](http://www.chuidiang.org/clinux/funciones/rand.php), en la parte en la que hablan sobre la función ```srand()```. En este caso, él está haciendo uso de la hora del sistema como semilla en la generación de números pseudo-aleatorios en la línea ```srand(time(NULL))```. Insisto en que **mi respuesta no es errónea**. – akmsw Feb 28 '20 at 14:51
  • Lo que es erróneo es la frase que he citado entre comillas y en cursiva. Del resto no he opinado. – PaperBirdMaster Feb 28 '20 at 14:56
  • El enlace que pasas, no indica nada sobre que `srand()` tenga una "*dependencia temporal*". Lo más cercano que dice es que puedes usar la hora del sistema como semilla de la generación de números pseudo-aleatorios. – PaperBirdMaster Feb 28 '20 at 14:59
  • Es precisamente eso a lo que hago referencia; él está haciendo uso de ello para obtener números pseudo-aleatorios y, entre línea y línea de código, hay un lapso de tiempo que hace que los números generados sean distintos. Eso fue lo que aclaré en mi comentario anterior. Es casi lo mismo que decir que llama a ```rand()``` dos veces. Intentaba resaltar ese concepto. Me he expresado mal, al parecer. Pido disculpas por el malentendido. – akmsw Feb 28 '20 at 15:06
  • **No**. El lapso de tiempo entre llamada y llamada a `rand()` no es lo que provoca que los números generados sean distintos ni la generación de un número distinto tiene relación alguna con el tiempo entre llamadas. Cada llamada a `rand()` genera un número pseudoaleatorio distinto, independientemente del lapso de tiempo entre llamadas. – PaperBirdMaster Feb 28 '20 at 15:20
1

Cada vez que llamas a rand() obtienes un número pseudo-aleatorio entre 0 y RAND_MAX, así que si en tu primera llamada obtienes (por ejemplo) 1000:

printf("Numero aleatorio generado: %d", rand()); // Muestra "Numero aleatorio generado: 1000"

Pero en tu segunda llamada obtienes otro número, por ejemplo 42:

x=rand()%11; // rand() devuelve '42', x obtiene '9'

El residuo de dividir 42 entre 11 es 9, pero el residuo de dividir 1000 entre 11 es 10, así que no te va a coincidir. Seguramente querías hacer esto:

int main(void)
{
  srand(time(NULL));
  int x=rand();

  printf("Numero aleatorio generado: %d", x);
  printf("\nNumero aleatorio acotado entre (0,10) generado: %d", x%11);
  return 0;
}

Otras cosas a tener en cuenta.

La función main debe tener int como tipo de retorno y si no va a recibir parámetros, su lista debe contener void y es aconsejable que devuelva algo al acabar. Lee este hilo para saber más.

La distribución de los números pseudo-aleatorios generados por rand() es uniforme, por lo que si calculas el módulo sobre un número que no es divisor de RAND_MAX, estarás falseando la distribución. Dado que 11 es un número primo, éste no será divisor de RAND_MAX.

Suponiendo que RAND_MAX tiene como valor 2147483647, si evaluamos rand()%11:

  • El número 0 aparecería 195225787 veces: 9,09090913%
  • El número 1 aparecería 195225786 veces: 9,09090908%
  • El número 2 aparecería 195225786 veces: 9,09090908%
  • El número 3 aparecería 195225786 veces: 9,09090908%
  • El número 4 aparecería 195225786 veces: 9,09090908%
  • El número 5 aparecería 195225786 veces: 9,09090908%
  • El número 6 aparecería 195225786 veces: 9,09090908%
  • El número 7 aparecería 195225786 veces: 9,09090908%
  • El número 8 aparecería 195225786 veces: 9,09090908%
  • El número 9 aparecería 195225786 veces: 9,09090908%
  • El número 10 aparecería 195225786 veces: 9,09090908%
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82