3

why does the following c code produce real numbers only ranging between 0 and 1(eg: 0.840188,0.394383...etc) for double a,b when the value for RAND_MAX appears to be 0.000000 . Shouldn't RAND_MAX set the maximum value for the number generated by rand() function ?

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {

    double a,b,c;
    for (int i=0;i<100;i++){
    a=(double)rand()/(double)RAND_MAX;
    b=(double)rand()/(double)RAND_MAX;
    c=a-b;
    printf("itteration : %d values a=%f,b=%f,c=%f, RAND_MAX=%f \n",i,a,b,c,RAND_MAX);
    }  
    return 0;
    }
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • if x is between 0 and max, the result of x / max will always between 0 and 1 that simple math. Plus `RAND_MAX` isn't a double it's an int so use %d for printing it with printf. rand is not suitable to generate double number it's design for int number and it's not very "random". You should search library that handle random in C. – Stargateur Aug 28 '18 at 06:09
  • ref. also : [Why does printf("%f",0); give undefined behavior?](https://stackoverflow.com/questions/38597274/why-does-printff-0-give-undefined-behavior) – Sander De Dycker Aug 28 '18 at 06:40

3 Answers3

10

RAND_MAX is an integral constant, but you are printing it using the %f specifier (used for double), which is undefined behavior (and in your case happens to print 0). Use %d and you'll see the actual value of RAND_MAX.

By the way, pretty much any decent compiler will warn you about that invalid printf if you crank the warnings high enough. Make sure to do so, C and C++ are full of traps enough, at least let the compiler help you when it can.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • ah yes thanks ! but a quick look at the source code shows `#define RAND_MAX 2147483647` but RAND_MAX is not defined as an integer just an immediate value with no type. does the compiler take an immediate value and assign it as an integer type by default ? – TheSprintingEngineer Sep 03 '18 at 02:23
  • @TheSprintingEngineer a `#define` creates a macro, which is brutal textual substitution, so whenever you write `RAND_MAX` it's exactly as if you wrote `2147483647`; now, this value is an decimal integer literal - as it matches the corresponding grammar production, i.e. `[1-9][0-9]*`. The type of decimal integer expressions is decided through an algorithm detailed into the standard, which essentially goes like "take the parsed number and try to fit it into `int`, `unsigned int`, `long`, `unsigned long`, `long long`, `unsigned long long`; the first that can represent it, is its type". – Matteo Italia Sep 03 '18 at 05:56
  • By the way, it's interesting to note that the standard asks for `RAND_MAX` just to be a "constant integral expression", which does not pose any limit to its specific integer type, so in theory an implementation may have a `#define RAND_MAX 32767ULL` (that is an `unsigned long long` literal); hence, for maximum portability, when printing it one should cast it to `int` first, otherwise the `%d` specifier may be incorrect (OTOH there's no risk of overflowing in the cast, as `RAND_MAX` is the maximum value that `rand()` can return, and it returns an `int`, so it must surely fit). – Matteo Italia Sep 03 '18 at 06:02
1

...the value for RAND_MAX appears to be 0.000000.

You are printing an integer using the specifier for a double. This is undefined behaviour.

From the C99 standard (N1256).

7.19.6.3 The printf function
...
2. The printf function is equivalent to fprintf with the argument stdout interposed before the arguments to printf.

7.19.6.1 The fprintf function
....
9. If a conversion specification is invalid, the behaviour is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

So it prints 0.000 for RAND_MAX. Your other question:

Shouldn't RAND_MAX set the maximum value for the number generated by rand() function ?

rand() returns a pseudo-random number in the range of 0 to RAND_MAX. RAND_MAX is a constant whose default value may vary between implementations but it is granted to be at least 32767.

But floating point division of rand() with RAND_MAX will yield a value between 0 and 1.

P.W
  • 26,289
  • 6
  • 39
  • 76
0

RAND_MAX is an integer and when you print it with %f, in binary it is truncated. In actual , 0 is what the last several number of RAND_MAX in binary show you in decimal

Raw
  • 23
  • 3