GP2X Random Numbers


Pickle

Mega GP Mania
Joined
May 30, 2006
Messages
5,518
Location
Detroit, Michigan
Website
Visit site
In my project I need to generate random numbers. I wanted to generate random numbers between a given range. Searching the web ive come across this solution, but it seems like rand is unstable. I have random [ no pun intended :) ] lockups in the application, I think this is the code responsible. I commented the srand line first then the rand line. No lock up once the rand line is not used.
Is there a undefined condition for modulus, like a divide by zero condition?

CODE

int16_t RandomValue( int16_t low, int16_t high )
{
int16_t num = 0;

srand((uint8_t)time(0) * rand());
num = rand() % (high - low + 1) + low;

return num;
}



Update: I think I solved my own issue, n % 0 is undefined (its divide by zero). I need to add some code to verify this is the lockup code.
 
That's interesting. I've done some research on creating a function that generates numbers which have a random distribution. Not the same thing as a random number generator. I *always* want F(5) to be 0.165236262, but F(x) for all x=0..2^64-1 gives a random distribution of numbers where F(4) and F(5) aren't obviously related.

Try looking up the Wikipedia article on pseudo-random number generation. The math for getting one random number from an existing seed isn't too hard.

http://en.wikipedia.org/wiki/Pseudorandom_number_generator
http://en.wikipedia.org/wiki/Linear_congruential_generator (I'm looking at modifying this algorithm, there some nice sample values further down the article)

EDIT: Ahh, you're looking at using the existing rand() function, ignore what I just said. (I shall not post on autopilot) :)

You just have to ensure high>=low... That will make sure you don't mod by zero. (remember, "mod zero" means "Divide by zero, what's the remainder?" That's uber-undefined.)
 
Under Linux (gp2x), it shouldn't lockup, it should just abort.

[squidge@router ~]$ gcc -xc -
main(){printf("%d\n",5%0);}
<stdin>: In function ‘main’:
<stdin>:1: warning: incompatible implicit declaration of built-in function ‘printf’
<stdin>:1: warning: division by zero
[squidge@router ~]$ ./a.out
Floating point exception
[squidge@router ~]$

I'd expect the same on the gp2x.

For your lockup issue, i'd check the result from your random function. Maybe its getting stuck at a constant value, I don't see how though from your code.

Then again, maybe you try something a little more randomer ;)
 
ok, I did some tests (running it in mingw by the way)
Added a break point when either value is 0 and it seems to step through it fine.

So i took out the whole function again and the mystery lockup still happens.
Any tools or ideas on how to debug this?
 
Dunno, a couple of thoughts...

Make the function return high, or low, or (high+low)/2.. derandomize it. Does it still crash?

If not, it would be good to know what values it's crashing on. Can you throw a little debug code in there?

You could try commenting out srand, or even replacing rand() with, say, 5. If it stops the crash, the problem is in the rand or srand function.
 
Trevor Bradley said:
Dunno, a couple of thoughts...

Make the function return high, or low, or (high+low)/2.. derandomize it. Does it still crash?

If not, it would be good to know what values it's crashing on. Can you throw a little debug code in there?

You could try commenting out srand, or even replacing rand() with, say, 5. If it stops the crash, the problem is in the rand or srand function.
yeah ive commented it out so the lockup is somewhere else, I was asking about ideas where it could be.
I think I will need to put stuff out on command line and work my way down into the code to find the hang up.
 
Last edited by a moderator:
Maybe it is some code optimization failure(on compiler)?

try compare (high - low + 1)==0 begore %-ing it :)
 
If your compiling with -O3, try disabling optimisation.

By "lockup" I assume your program just stops until you kill it with SIGINT? or is SIGKILL necessary?
 
You probably shouldnt have srand() in your random number function... Im not sure if it would break it, but all it would do is give you randomer numbers if you didnt move it to startup code
 
Squidge said:
If your compiling with -O3, try disabling optimisation.

By "lockup" I assume your program just stops until you kill it with SIGINT? or is SIGKILL necessary?
im using -O2, but that still a good idea I will give it a shot. And you right about the lockup requiring me to kill the process. Again im debugging in windows not linux ;-) I might try running it in linux though.

Update: there no optimisation enabled for my debug build. But theres some other code I think may be suspect:

CODE

while( tmrFPSLimit.get_ticks() <= MS_PER_FRAME )
{
//SDL_Delay( (MS_PER_FRAME - tmrFPSLimit.get_ticks()) / 2 ); // Go to sleep
SDL_Delay(5);
}



The idea of this code was to sleep in between frames. This is the only place where the thread should be able to sleep. I set it a hardcoded 5 ms and so far no lockups.
I think this may be the problem, when the lockup occurs it takes 0 processor load, like its gone to sleep. I need to investigate it further, but I think this is it.

Update 2:
This has to be it.
CODE

(MS_PER_FRAME - tmrFPSLimit.get_ticks()) / 2


This code is sometimes returning a negative value, SDL_Delay only takes an unsigned number, so -1 would be 65535 ms. Thus a nice long delay, or what appears to be a lockup.
Ive verified that code is returning negative numbers. It also explains why hard coding it to 5 worked.

Made life a bit more simple:
CODE

delay = MS_PER_FRAME - tmrFPSLimit.get_ticks();
if( delay > 0 )
{
SDL_Delay( delay ); // Go to sleep
}
 
Last edited by a moderator:
zacaj said:
You probably shouldnt have srand() in your random number function... Im not sure if it would break it, but all it would do is give you randomer numbers if you didnt move it to startup code
It shouldn't break it, but running it once at the beginning is the better way to do it. If you have it in the function, and the function is called twice in a row, you'll get the same "random" number because the time is the same.
 
Last edited by a moderator:
Capn_Fish said:
zacaj said:
You probably shouldnt have srand() in your random number function... Im not sure if it would break it, but all it would do is give you randomer numbers if you didnt move it to startup code
It shouldn't break it, but running it once at the beginning is the better way to do it. If you have it in the function, and the function is called twice in a row, you'll get the same "random" number because the time is the same.

From what ive seen it doesn't seem to make a difference having srand for the random numbers I need. I just need random x,y coordinates for some graphics, so if some of the numbers repeat or form pattern I cant tell.

The original problem was solved with the change to the delay code.
 
Last edited by a moderator:
Pickle said:
Capn_Fish said:
zacaj said:
You probably shouldnt have srand() in your random number function... Im not sure if it would break it, but all it would do is give you randomer numbers if you didnt move it to startup code
It shouldn't break it, but running it once at the beginning is the better way to do it. If you have it in the function, and the function is called twice in a row, you'll get the same "random" number because the time is the same.

From what ive seen it doesn't seem to make a difference having srand for the random numbers I need. I just need random x,y coordinates for some graphics, so if some of the numbers repeat or form pattern I cant tell.

The original problem was solved with the change to the delay code.

Delay code?

My point is that if you only run srand once at the beginning, you don't HAVE to delay to get new random numbers.

Sorry if I misunderstood you.
 
Last edited by a moderator:
Capn_Fish said:
Delay code?

My point is that if you only run srand once at the beginning, you don't HAVE to delay to get new random numbers.

Sorry if I misunderstood you.
sorry :rolleyes: , the delay code had nothing to do with the random number code. I thought the lockup was the random number code, but its delay code that is used in the frame limit code.
But your right about the srand only being needed once.
 
Last edited by a moderator:
Back
Top