• Viernes 29 de Marzo de 2024, 12:45

Autor Tema:  Implementación de Rnd y Randomize  (Leído 2117 veces)

jaumegs

  • Miembro MUY activo
  • ***
  • Mensajes: 110
    • Ver Perfil
Implementación de Rnd y Randomize
« en: Miércoles 1 de Diciembre de 2010, 14:17 »
0
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.

¿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.
« última modificación: Domingo 27 de Enero de 2013, 08:41 por iron man »

jaumegs

  • Miembro MUY activo
  • ***
  • Mensajes: 110
    • Ver Perfil
Re: Implementación de Rnd y Randomize
« Respuesta #1 en: Miércoles 1 de Diciembre de 2010, 18:42 »
0
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.