NXC random numbers / random seed

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NXC random numbers / random seed

Post by HaWe »

hi,
while rand() is supposed to be the same in NXC as in ANSI C, I still don't see how to generate a random seed like

Code: Select all

srand ( time(NULL) );
// or
srand (1);
Although I already found a function SysRandomNumber, I still don't understand how to use it and how it's possible to mimicry exactly the ANSI C srand() maybe using a #define.

code example:

Code: Select all

int main ()
{
  printf ("First number: %d\n", rand() % 100);
  srand ( time(NULL) );
  printf ("Random number: %d\n", rand() % 100);
  srand ( 1 );
  printf ("Again the first number: %d\n", rand() %100);

  return 0;
}
Thanks in advance!
m-goldberg
Posts: 73
Joined: 29 Sep 2010, 12:05

Re: NXC random numbers / random seed

Post by m-goldberg »

I brought up this question with John Hansen over email last year. He wrote back the following:
The standard firmware doesn't expose a way to seed the random number generator used internally by the RandomNumber system call. I haven't ever bothered to expose it in the enhanced NBC/NXC firmware either. Here's the firmware code:

Code: Select all

NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[])
{
   static UBYTE count = 0;
   SWORD random;
   if (count == 0)
      srand(dTimerRead());
   if (count > 20)
      count = 0;
   else
      count++;
   //!!! IAR's implementation of the rand() library function returns signed 
   // values, and we want it that way.
   // Some stdlib implementations may return only positive numbers, so be wary 
   // if this code is ported.
   random = rand();
   *((SWORD *)ArgV[0]) = random;
   return NO_ERR;
}
So this means that every 20 times you call the RandomNumber system call function it will reseed by calling srand and passing in the current firmware timer value (1ms resolution).
You can see from this that srand is being called continually by the firmware, so having it available explicitly won't help much. The rand function in NXC simply doesn't work much like the one in Unix.
Regards, Morton
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC random numbers / random seed

Post by HaWe »

Morton,
thx for your reply!
As my English is very poor I actually don't understand the meaning of what you wrote... :oops:
so what does this mean
So this means that every 20 times you call the RandomNumber system call function it will reseed by calling srand and passing in the current firmware timer value (1ms resolution).
in simple words related to both
- the srand seed which you need at every new program start (so that you won't get the same series of "random " numbers each time
- and -
- every following rand call

Of course,
a random number (series) is needed in order NOT to have the same series each time in each program run... :geek:
so how can I get independend random number series starting with a new seed each time?
m-goldberg
Posts: 73
Joined: 29 Sep 2010, 12:05

Re: NXC random numbers / random seed

Post by m-goldberg »

I didn't write it. John Hansen wrote it. I am quoting from an email he sent me. The code in the quoted section comes from the NXT firmware. It shows how LEGO implemented the random number generator in the firmware.

I would say that John is telling us (and the quoted code supports this) that there is no use for an exposed srand API call because the firmware is calling srand internally every 20 msec. I think that LEGO did this so the users would not need to remember to call srand themselves. Perhaps LEGO thought it would be too complicated for the younger users to understand how srand and rand interact with each other. That is just a guess, though.

One side effect of this is that it is impossible to use srand to get a repeatable sequence of pseudo-random numbers for testing purposes. This is too bad, but it is something we have to live with if John's firmware is to remain compatible with LEGO's.
Regards, Morton
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC random numbers / random seed

Post by HaWe »

ok, thank you!
I know that you partially quoted John's answer in what you wrote ;)
But if I understand you correctly, we will get at least ALWAYS an independent series of random numbers and NEVER identical series....(?)

Another point is - my personal "ceterum censeo" - it is not forbidden to John to make his EFW different AND better than the original one and NXC "Almost Completely Disputably C" ("ACDC") - (maybe using #ifdefines and a "100% compatibility checkbox" in the compiler settings)... :P
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: NXC random numbers / random seed

Post by gloomyandy »

Hi Doc,
You could always implement your own srand/rand functions and use those. The following link gives the version from gcc:
http://qa.coreboot.org/docs/libpayload/ ... ource.html

Andy
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC random numbers / random seed

Post by HaWe »

thx Andy, I appreciate your idea!
But to be honest, I don't understand how to make that code work for the "whole" srand and rand functionality:
srand(const int variant) for reproducible pseudo random numbers series and
srand( time(NULL) ) for "real independent" random number series

Code: Select all

00034 #include <libpayload.h>
00035 
00036 static unsigned int next = 1;
00037 
00038 int rand_r(unsigned int *seed)
00039 {
00040         *seed = *seed * 1103515245 + 12345;
00041         return (*seed % ((unsigned int)RAND_MAX + 1));
00042 }
00043 
00044 int rand(void)
00045 {
00046         return (rand_r(&next));
00047 }
00048 
00049 void srand(unsigned int seed)
00050 {
00051         next = seed;
00052 }

CMIIW, but as far as I see you will always get the same series of numbers with your code - but maybe it achieves this nevertheless using those pointer tricks (and here I have no idea how to mimcry this by NXC).
remember, I'm not a programmer, or a IT professional I'm just a simple Lego user ;)
Last edited by HaWe on 29 Jan 2011, 17:47, edited 1 time in total.
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: NXC random numbers / random seed

Post by gloomyandy »

if you call srand with a fixed number like say 1 or 27 or 42 you will get a different series of numbers returned from rand for each. But the series will be the same if you use the same seed (the value passed into srand). So to get a different set of numbers each time you run your program you need to get a "random seed" typically these come from things like the system time, or by timing something like the gab between two button presses (or if you are really serious from a white noise source).
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC random numbers / random seed

Post by HaWe »

yes, I also had the idea to use sth like a "press a btn to start program" loop at the program start, using the timer counter in the loop as a seed for the random function.
But nevertheless I still have no idea how to transcode your example into pointer-less code... :oops:
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: NXC random numbers / random seed

Post by gloomyandy »

try something like...

Code: Select all

static unsigned int next = 1;

int rand(void)
{
    next = next * 1103515245 + 12345;
   return (next % ((unsigned int)RAND_MAX + 1));
}

void srand(int seed)
{
    next = seed;
}
Note I've not tried the above and it is in C not NXC so you may need to adjust things a little...
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests