Home > front end >  Generate a random number between range (-0.5 , 0.5) in C
Generate a random number between range (-0.5 , 0.5) in C

Time:05-28

Consider the following C program :

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main()
{
    srand(time(NULL));

    for (int i = 0; i < 20;   i) {

        static float a = 0;
        a = (rand() % 2001 - 1000) / 2.e3;
        printf("%.4f ", a);
    }
}

This will successfully generate then print a list of random number between -0.5 to 0.5. For example :

./main.out
-0.2475 -0.3640 -0.3945 0.2995 0.0460 0.2230 -0.0340 0.1630 -0.2275 -0.3450 0.3560 -0.4335 -0.0025 -0.2980 -0.0505 -0.1815 0.3115 -0.4465 -0.1325 -0.2340

I checked the Precedence of Operators and still don't understand how the expression (rand() 01 - 1000)/2.e3 works.

(especially where does the negative sign comes from)

I hope someone could explain this, thank you.

CodePudding user response:

 a = (rand() % 2001 - 1000) / 2.e3;

rand() is evaluated first

    a = (rand() % 2001 - 1000) / 2.e3;
         ^^^^^^ int between `0` and `RAND_MAX` inclusive

Then the modulus operator generates a value between 0 and 2000.

    a = ([0 .. 2000] - 1000) / 2.e3;
         ^^^^^^^^^^^ int

Then that value has 1000 subtracted, becoming a value between -1000 and 1000

    a = ([-1000 .. 1000]) / 2.e3;
         ^^^^^^^^^^^^^^^ int

Then, divided by 2000.0 (or 2.e3) generates a double between -0.5 and 0.5

    a = [-0.5 .. 0.5];
        ^^^^^^^^^^^^^ double

CodePudding user response:

Let's analyze the expression (rand() % 2001 - 1000) / 2.e3:

  • the rand() function defined in <stdlib.h> returns a pseudo random integer of type int in the range 0 to RAND_MAX inclusively. RAND_MAX is a constant also defined in <stdlib.h> whose value is at least 32767.

  • rand() % 2001 computes the remainder of the division by 2001. Since rand() is positive, the result is a pseudo random number in the range 0 to 2000 inclusive, with a small bias caused by 2001 not dividing RAND_MAX evenly.

  • rand() % 2001 - 1000 is evaluated as (rand() % 2001) - 1000, the range of the result is shifted by 1000 toward the negatives, namely between -1000 and 1000 inclusively.

  • to evaluate (rand() % 2001 - 1000) / 2.e3, the value obtained from the previous steps is converted to type double and divided by 2.e3, which would be more readable as 2000.0. Hence the result is a floating point value of type double with 2001 possible distinct values between -0.5 and 0.5 inclusively.

  • a = (rand() % 2001 - 1000) / 2.e3; converts this double value to float, the type of a. The float value will be implicitly converted back to type double when passed to printf, this conversion does not produce exactly the same number in many cases.

  • note that there is no reason to define a as a static variable.

Here is an alternative implementation that produces more distinct values in the same inclusive range with a slightly less biased distribution:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));

    for (int i = 0; i < 20;   i) {
        double a = rand() / (double)RAND_MAX - 0.5;
        printf("%f ", a);
    }
    printf("%\n");
    return 0;
}
  • Related