Page 1 of 1

Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Tue Sep 10, 2024 12:32 pm
by regan.xavier
Hi,

I have a requirement to generate 10 digits random value in my esp32 project.

I would like to know, does this esp_random() can return a single digit by any chance?

And can the function returns the same value more than once?

Re: Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Wed Sep 11, 2024 4:14 am
by ESP_Sprite
According to the docs, it returns a "Random value between 0 and UINT32_MAX", so yes, it can certainly return a single-digit number (otherwise the range would be 10 to UINT32_MAX. Given it's a true random number generator, the result you get each time you call it is independent from the number you got on previous calls, For instance, for each call, there is a 1/UINT32_MAX (or 0.0000000232%) chance that the number is exactly the same as the previous number.

Re: Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Wed Sep 11, 2024 1:19 pm
by MicroController

Code: Select all

randDigit = (esp_random() * 10ull) >> 32;
should yield a uniformly distributed random integer from [0,9].
This approach can be modified to generate a somewhat uniformly distributed number of up to 9 digits (base10) from a single call to esp_random().
Alternatively,

Code: Select all

uint32_t result;
do {
  result = esp_random() >> 2;
} while( result >= 1000000000 );
will get you a uniformly distributed 9-digit (base10) random integer.

Re: Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Thu Oct 10, 2024 4:15 am
by regan.xavier
Thanks! Helpful.

Re: Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Thu Oct 10, 2024 6:33 am
by chegewara
MicroController wrote:
Wed Sep 11, 2024 1:19 pm

Code: Select all

randDigit = (esp_random() * 10ull) >> 32;
should yield a uniformly distributed random integer from [0,9].
I dont think so.
I believe this code will give most of the time 0 as a result. Half of randDigit values will be in range of 0 to 2^15, then

Code: Select all

if(randDigit <= 2^15)
then (randDigit * 10) >> 32 == 0
Is that correct?

I think the easiest way is always the easiest way:

Code: Select all

digit = esp_random() % 10

Re: Can esp_random() return single digit? Can it return the same random number more than once?

Posted: Thu Oct 10, 2024 9:44 am
by MicroController
It's the integer/fixed-point equivalent of

Code: Select all

double r = (double) esp_random();      // -> 0.0 <= r < 4294967296.0
double r_norm = r / 4294967296.0d;     // -> 0.0 <= r_norm < 1.0
int randDigit = (int)(r_norm * 10.0d); // -> randDigit = floor( r_norm * 10 ) -> 0 <= randDigit < 10
Note that, because esp_random() returns 32 bits, the probability of (esp_random() < (1<<15)) is (1<<15)/(1<<32), i.e. 1/131072.