|
|
View previous topic :: View next topic |
Author |
Message |
puffeltje
Joined: 23 Mar 2014 Posts: 2
|
change RAND_MAX |
Posted: Sun Sep 28, 2014 3:52 am |
|
|
Hi,
I'm totally new to the language C. I always programmed in basic.
I want to change the value of RAND_MAX. At the moment i have defined it before including <STDLIB.H>. This works well.
Is it possible to change the value by code after the #define ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Sun Sep 28, 2014 4:38 am |
|
|
No.
However just scale the number as you want.
If you don't define 'RAND_MAX', it uses 32767.
Leave it at this value, and then just scale the number how you want. So something like:
Code: |
//leave RAND_MAX undefined
int16 scaled_rand(int16 max)
{
int32 temp_32;
temp_32=(int16)rand();
temp_32=temp_32*((int32)max*2)+32767L;
//you now have a 32bit integer, comprising the product of the rand (0-32767) value,
//and your 'max', times 2, and 32767 added
//Now adding 32767 gives effectively 4/5 rounding at the next stage,
return (temp_32)/65536;//The compiler replaces this with shifts
}
|
Now visualise the 'rand' returns it's maximum value (32767), and you specify '100'. You get (32767*200)+32767 = 6586137. Divide by 65536, and the integer result is 100. The specified 'max'. It'll give smoothly distributed values right across your number range, for 0 to 'max', and you can change max whenever you want. |
|
|
puffeltje
Joined: 23 Mar 2014 Posts: 2
|
|
Posted: Sun Sep 28, 2014 5:02 am |
|
|
Thanks, i'm going to implement this solution.
I also did a search on the internet and found this solution:
It does the job, but i can't find '%' in the helpfiles of CCS. Is this also a usable solution or is it better to use your solution?
-edit- I found the modulus operator. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Sun Sep 28, 2014 7:15 am |
|
|
%, is a standard C function. Modulus. CCS has it, problem is that because of the way integer maths works, you won't get a nice smooth progression with equal probabilities to all the values. By multiplying 'up', and adding the offset, I get as close as you can to this, and the solution is slightly smaller/quicker as well.
It's actually possible to shrink it a tiny amount further by using a union to do the extraction of the 16bit result, but the amount is small, the optimiser is quite efficient here.
The 'efficient' version, is:
Code: |
int16 scaled_rand(int16 max)
{
union {
int32 temp_32;
int16 temp_16_arr[2];
} joiner;
joiner.temp_16_arr[0]=(int16)rand()*2;
joiner.temp_16_arr[1]=0;
joiner.temp_32*=(int32)max;
joiner.temp_32+=32767L;
//you now have a 32bit integer, comprising the product of the rand (0-32767) value,
//and your 'max', times 2, and 32767 added
//Adding 32767 gives effectively 4/5 rounding at the next stage,
return joiner.temp_16_arr[1];
}
|
This is about 20 instructions quicker than the earlier version, but makes it relatively harder to work out how it works. This is about 50 instructions quicker than using the modulus solution. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|