I aim to generate packets accoding to Poisson distribution in Contiki Cooja using MSP430 Experimenter board (Exp430) platform (same issue applies to Zolertia Z1 motes which also have MSP430-based MCU). I included the math library and coded the Poisson distribution as:
float nextTime = (-2.000) * logf((rand() / (float)RANDOM_RAND_MAX));
where the actual formula behind the code is -a*ln(rand) in which rand must be a floating point number between 0 and 1. I created a simulation and tested the generated nextTime's and I realized that it generated 0.000 quite often. Then I broke the code into small pieces to see what values are causing 0.000 to be generated as:
float inner1 =(float)( (rand() / (float)RANDOM_RAND_MAX));
float inner2 = logf(inner1);
float nextTime = (float) (-2.000)*inner2;
One of value of inner1 causing nextTime to be calculated as 0.000 was 0.135. Then I set inner1 to 0.135 and reloaded the simulation and what I got was inner2 as -2.2 and nextTime as 4.5 as it should be. This confused me, because when I set the inner2 to a constant value, nextTime is calculated correctly. But exactly this value was causing nextTime to be 0.000 previously. I'm just really curious about it, why it happens in this way. Btw, I know printing floats in Contiki is not supported and I used two different solutions to print these float values correctly(How to print floating point value using putchar? and https://sourceforge.net/p/contiki/mailman/message/25936733/) .
I'm surprised you can use rand().
In contiki, for generate rand number you need to use random_rand()
And include : #include "lib/random.h"
Edit : For more explanation :
The code of random_rand()
:
unsigned short
random_rand(void)
{
/* In gcc int rand() uses RAND_MAX and long random() uses RANDOM_MAX=0x7FFFFFFF */
/* RAND_MAX varies depending on the architecture */
return (unsigned short)rand();
}
So it return unsigned short, whatever happen. If the RAND_MAX is not well defined, you'll have an overflow, giving you a signed number. Casting into unsigned do the trick.