SoloCodigo

Programación General => Visual Basic 6.0 e inferiores => Mensaje iniciado por: jaumegs en Miércoles 1 de Diciembre de 2010, 14:17

Título: Implementación de Rnd y Randomize
Publicado por: jaumegs en Miércoles 1 de Diciembre de 2010, 14:17
Necesito implementar las funciones Rnd y Randomize de Visual Basic en un lenguaje más rápido para un ejercicio recreativo de criptografía. Es preciso que sean las mismas funciones y que devuelvan los mismos valores.

Por ahora tengo lo siguiente:

Código: C
  1.  
  2. #define  X0  0x50000L    // 327680
  3. #define  A   0x43fd43fdL // 1140671485
  4. #define  C   0xc39ec3L   // 12820163
  5. #define  M   0xffffffL   // 2^24 - 1
  6.  
  7. long seed = X0;
  8.  
  9. float Rnd (long Number)
  10. {
  11.    if (Number > 0)
  12.    {
  13.       seed = (seed * A + C) & M;
  14.    }
  15.    else if (Number < 0)
  16.    {
  17.       // No estoy seguro de esta parte...
  18.    }
  19.    return (float) seed / (float) 16777216.0;
  20. }
  21.  
  22.  

El resultado de llamar a Rnd() con un argumento nulo o positivo es el esperado, sin embargo, no se como implementar Rnd() cuando el argumento es negativo ni tampoco Randomize().

He encontrado una web que supuestamente explica el funcionamiento de ambas funciones, pero o yo no lo entiendo o la explicación de Randomize es incorrecta. La dirección es la siguiente  http://www.experts-exchange.com/A_11114.html (http://www.experts-exchange.com/A_11114.html).

¿Alguien tiene idea de como implementar Rnd() y Randomize() de Visual Basic en C?

Gracias.


Nota del administrador: Modificado el enlace al artículo ya que http://www.15seconds.com/issue/051110.htm ha dejado de funcionar.
Título: Re: Implementación de Rnd y Randomize
Publicado por: jaumegs en Miércoles 1 de Diciembre de 2010, 18:42
Ya he averiguado el comportamiento completo de Rnd():

Código: C
  1. long long seed = 0x50000L;
  2.  
  3. float rnd (float number)
  4.  
  5. {
  6.    unsigned char* byte;
  7.    long long result;
  8.  
  9.  
  10.    if (number > 0)
  11.  
  12.    {
  13.  
  14.       seed = (seed * 0x43fd43fdLL + 0xc39ec3LL) & 0xffffffLL;
  15.  
  16.    }
  17.  
  18.    else if (number < 0)
  19.  
  20.    {
  21.       byte = (unsigned char *) &number;
  22.       result = (byte[2] << 16) + (byte[1] << 8) + byte[0] + byte[3];
  23.  
  24.       seed = (result * 0x43fd43fdLL + 0xc39ec3LL) & 0xffffffLL;
  25.  
  26.    }
  27.  
  28.  
  29.  
  30.    return (float) seed / (float) 16777216.0;
  31.  
  32. }
  33.  

Es necesario usar el tipo long long, pues en la multiplicación se puede producir desbordamiento.

Esta versión de Rnd() funciona exactamente igual que la de Visual Basic; al menos es lo que parece tras realizar múltiples pruebas (0, positivos, negativos...).

Respecto a Randomize(), no tengo ni idea de por donde pillarla.

Saludos.