Go Down

Topic: random int not long?? help appreciated (Read 4941 times)previous topic - next topic

dustybike

May 26, 2008, 11:51 amLast Edit: May 26, 2008, 11:55 am by dustybike Reason: 1
hi everyone  yet another question haha

ok sh when you do a eg:

Code: [Select]
`Serial.println(random(100000000, 999999999));`

i get an output like(im using randomseed in the setup btw):

Code: [Select]
`100014190100015095100018554100023236100004893100004297100003548100031779100029752100006162100023813100029914100012502100028386100021643100001407100023755100008466100015325100024320100002781100022222100010656100020318100023525100009803100009635100007011100004047100007227100002938100007327100004194100009321100008931100007602100005747100029643100017968100012811100007210100011294100001836100028688100020796`

so im wanting it to have a bigger random but only the first 5 digits randomise and never over 32767 so i figured that the random() call is only an int  but i need it to be a long  or even better up to a unsigned long so i can get a nice lot of randomness rite up to 4,294,967,295  (unsigned long max number)

if someone can tell me how to do this that would be great, if its a microcontroller thing or software thing please tell me i would quite like to know why this happens.

cheers

callum

bens

#1
May 26, 2008, 12:09 pm
The simplest thing I can think of: generate your random unsigned long by making two calls to random(), the first of which gives you your two low bytes and the second of which gives you your two high bytes.  Either that or you can google for random number generator algorithms and create your own implementation that isn't limited to two bytes (this probably wouldn't be very hard).

- Ben

dustybike

#2
May 26, 2008, 12:16 pm
ah thank you ben   first to help once again  i appreciate it  ill look for the latter method.

if anyone knows the reason why it does it i would quite like to know

cheers all

bens

#3
May 26, 2008, 12:25 pm
I did a little more digging and I think I can give you a more satisfying explanation.  I found the Arduino random functions in WMath.cpp:

Code: [Select]
`long random(long howbig){  long value;  if (howbig == 0){    return 0;  }  return rand() % howbig;}long random(long howsmall, long howbig){  if(howsmall >= howbig){    return howsmall;  }  long diff = howbig - howsmall;  return random(diff) + howsmall;}`

These use the rand() function defined in stdlib.h, and rand() returns a signed int.  So what this means is that random() will return a number that is always less than or equal to 0x7FFF, even though the definition makes it seem like it can handle longs.  This would seem to be a bug in the implementation of random().  If you then look at what this means for random(howsmall, howbig), you see that you are returning a random signed int plus howsmall, which can be a long.  The result is exactly what you have already observed.

I think either the random functions should be rewritten to take arguments that are ints, or they should be implemented in a way that actually returns random longs.

- Ben

dustybike

#4
May 26, 2008, 12:37 pm
thankyou very much ben i appreciate it so much    its nice to know it wasnt my fault     can i post that into the sugestions forum  or you can of course   jus tell me

cheers mate

callum

bens

#5
May 26, 2008, 12:48 pm
I just posted something there with a proposed fix.  Hopefully I thought it through well enough and didn't neglect some crucially important detail.

- Ben

follower

#6
May 26, 2008, 12:53 pmLast Edit: May 26, 2008, 12:54 pm by follower Reason: 1
Quote
Hopefully I thought it through well enough and didn't neglect some crucially important detail.

Heh, nothing like learning from others' mistakes... :-) *cough*debian*cough*

--Phil.

dustybike

#7
May 26, 2008, 12:59 pm
hay ben any chance u could pop up that file uv changed?   ill give it a right old test hehe

cheers

callum

bens

#8
May 26, 2008, 11:11 pm
The simplest thing for you to do would probably be to make the change in your own arduino-0011 distribution.  The file in question is:

arduino-0011/hardware/cores/arduino/WMath.cpp

I suggest you make a backup of the file, and then try changing the random() function as I mentioned in my Bugs & Suggestions thread.  If you test it out, please let me know how it works.

- Ben

walterr

#9
May 27, 2008, 08:58 pm
The built in random function for any particular language is rarely very random or particularly useful for more than simple uses. The textbook example is using random numbers to calculate pi. It only works if the numbers are reasonably random and have a large range.

You can implement a much better random number generator with a few lines of code. It's on my to do list to dig up the one I wrote in college and port it to the Arduino.

I think I found it. Here it is in a form that might run on the Arduino, but it's untested.
Code: [Select]
`unsigned long gXOld; // last random valueInitRealRandom(){      gXOld = millis();}double RandomNumber(){      unsigned long      temp;                        temp = 663608941*gXOld;      gXOld = temp;      return(((double)temp)/((double)4294967295));}`

Go Up