Author Topic: Best way for random number generation?  (Read 4437 times)

0 Members and 1 Guest are viewing this topic.

Offline compu

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 275
  • Rating: +63/-3
    • View Profile
Best way for random number generation?
« on: March 04, 2011, 03:27:29 pm »
Hi, I have to generate random numbers on the Nspire... Till now I have been using this function:
Code: [Select]
int random(int max)
{
    unsigned int *counter = (unsigned int *) 0x9001000C;
    return *counter/(65535/max);
}
(same way as in nTris)

This works fine for me on the emulator, but on real hardware It often gives the same numbers :(
In my case I'm using random(3) for random level generation in Shunledge (whole source here, topic here).. so, what could be a better way to do this?

PS: Yes, I have initialized the timer ;)
« Last Edit: March 04, 2011, 03:29:14 pm by compu »

Offline christop

  • LV3 Member (Next: 100)
  • ***
  • Posts: 87
  • Rating: +20/-0
    • View Profile
Re: Best way for random number generation?
« Reply #1 on: March 04, 2011, 05:38:04 pm »
I just use the classic linear congruential PRNG in one of my programs:
Code: [Select]
unsigned prngseed;

int rand()
{
        prngseed = 1103515245UL*prngseed + 12345UL;
        return (unsigned)prngseed % ((unsigned)INT_MAX+1);
}

void srand(unsigned s)
{
        prngseed = s;
}
(This is a modification of my code so it works with 32-bit ints (assuming int is 32 bits on the Nspire). My program runs on a system with 16-bit ints)

These are actually implementations of the C standard functions rand() and srand(). It works pretty well considering its simplicity. It also doesn't rely on a timer to generate each successive value. You can set the seed using the timer though:
Code: [Select]
srand(*counter);

To use it with a maximum value you can do this:
Code: [Select]
/* RAND_MAX = 2147483647 with 32-bit int */
x = (unsigned long long)rand() * max / RAND_MAX;
Yeah, it uses 64-bit arithmetic (if long long is 64 bits, that is), but it is far more uniformly distributed than using "x/(65535/max)" as you are doing (except when max is an integer factor of 65535, in which case it's the same).
« Last Edit: March 04, 2011, 05:39:58 pm by christop »
Christopher Williams

Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Best way for random number generation?
« Reply #2 on: March 04, 2011, 06:15:45 pm »
Hi, I have to generate random numbers on the Nspire... Till now I have been using this function:
...
 so, what could be a better way to do this?

The *best* way would be Blum Blum Shub. The fastest way would probably be that LCRNG Chris posted.
« Last Edit: March 04, 2011, 06:16:04 pm by Qwerty.55 »
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline compu

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 275
  • Rating: +63/-3
    • View Profile
Re: Best way for random number generation?
« Reply #3 on: March 05, 2011, 02:47:12 pm »
christop, must INT_MAX be 4294967296 then ???
I don't get this to work :banghead:

Offline christop

  • LV3 Member (Next: 100)
  • ***
  • Posts: 87
  • Rating: +20/-0
    • View Profile
Re: Best way for random number generation?
« Reply #4 on: March 05, 2011, 05:24:49 pm »
Oh, I forgot to define INT_MAX. It's the maximum value of a signed int, so it's 2147483647 with 32-bit ints. It's the same as RAND_MAX.
Christopher Williams

Offline compu

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 275
  • Rating: +63/-3
    • View Profile
Re: Best way for random number generation?
« Reply #5 on: March 23, 2011, 04:09:11 pm »
Finally I found the time to fix my game, the levels are generated much better now.
Thanks for helping me out :)