Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

372
Visualizações
¿Por qué rand() + rand() producen números negativos?

Observé que la función de biblioteca rand() cuando se llama solo una vez dentro de un ciclo, casi siempre produce números positivos.

 for (i = 0; i < 100; i++) { printf("%d\n", rand()); }

Pero cuando agrego dos llamadas al rand() , los números generados ahora tienen más números negativos.

 for (i = 0; i < 100; i++) { printf("%d = %d\n", rand(), (rand() + rand())); }

¿Alguien puede explicar por qué veo números negativos en el segundo caso?

PD: inicializo la semilla antes del bucle como srand(time(NULL)) .

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

rand() está definido para devolver un número entero entre 0 y RAND_MAX .

 rand() + rand()

podría desbordarse. Lo que observa es probablemente el resultado de un comportamiento indefinido causado por un desbordamiento de enteros.

over 4 years ago · Santiago Trujillo Relatório

0

El problema es la adición. rand() devuelve un valor int de 0...RAND_MAX . Entonces, si agrega dos de ellos, obtendrá hasta RAND_MAX * 2 . Si eso excede INT_MAX , el resultado de la suma desborda el rango válido que puede contener un int . El desbordamiento de valores firmados es un comportamiento indefinido y puede hacer que su teclado le hable en lenguas extranjeras.

Como no hay ganancia aquí al agregar dos resultados aleatorios, la idea simple es simplemente no hacerlo. Alternativamente, puede convertir cada resultado en un unsigned int antes de la suma si eso puede contener la suma. O utilice un tipo más grande. Tenga en cuenta que long no es necesariamente más ancho que int , ¡lo mismo se aplica a long long si int tiene al menos 64 bits!

Conclusión: solo evita la adición. No proporciona más "aleatoriedad". Si necesita más bits, puede concatenar los valores sum = a + b * (RAND_MAX + 1) , pero eso probablemente también requiera un tipo de datos más grande que int .

Como su razón declarada es evitar un resultado cero: eso no se puede evitar agregando los resultados de dos llamadas rand() , ya que ambas pueden ser cero. En su lugar, puede simplemente incrementar. Si RAND_MAX == INT_MAX , esto no se puede hacer en int . Sin embargo, (unsigned int)rand() + 1 funcionará muy, muy probablemente. Probablemente (no definitivamente), porque requiere UINT_MAX > INT_MAX , lo cual es cierto en todas las implementaciones que conozco (que cubre bastantes arquitecturas integradas, DSP y todas las plataformas de escritorio, móviles y servidores de los últimos 30 años).

Advertencia:

Aunque ya se mencionó en los comentarios aquí, tenga en cuenta que agregar dos valores aleatorios no obtiene una distribución uniforme, sino una distribución triangular como lanzar dos dados: para obtener 12 (dos dados), ambos dados deben mostrar 6 . para el 11 ya hay dos variantes posibles: 6 + 5 o 5 + 6 , etc.

Entonces, la adición también es mala desde este aspecto.

También tenga en cuenta que los resultados que genera rand() no son independientes entre sí, ya que son generados por un generador de números pseudoaleatorios . Tenga en cuenta también que la norma no especifica la calidad o la distribución uniforme de los valores calculados.

over 4 years ago · Santiago Trujillo Relatório

0

Esta es una respuesta a una aclaración de la pregunta hecha en comentario a esta respuesta ,

la razón por la que estaba agregando era evitar '0' como el número aleatorio en mi código. rand()+rand() fue la solución rápida y sucia que me vino a la mente.

El problema era evitar el 0. Hay (al menos) dos problemas con la solución propuesta. Una es, como indican las otras respuestas, que rand()+rand() puede invocar un comportamiento indefinido. El mejor consejo es nunca invocar un comportamiento indefinido. Otro problema es que no hay garantía de que rand() no produzca 0 dos veces seguidas.

Lo siguiente rechaza cero, evita un comportamiento indefinido y, en la gran mayoría de los casos, será más rápido que dos llamadas a rand() :

 int rnum; for (rnum = rand(); rnum == 0; rnum = rand()) {} // or do rnum = rand(); while (rnum == 0);
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda