B07 Answer


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

/* Puzzle B07 -- print N random doubles 0.0 <= d < 1.0 */

double randDouble()
{
return (double)rand()/((double)RAND_MAX+1);
} const int limit = 100 ; int main(int argc, char *argv[]) { int j=0 ; double r; srand( time(NULL) ); for ( j=0; j < limit; j++ ) { r = randDouble() ; printf(" %12.10lf", r ); if ( j%5 == 4 ) printf("\n"); } printf("\n"); system("pause"); return 0; }

Comments: The division

(double)rand()/((double)RAND_MAX+1)

returns a double precision 0.0 when rand() is 0, and returns double precision 0.99996948 when rand() returns RAND_MAX. (This is assuming that RAND_MAX has the value 32767. Recall that the value for it varies between C environments.) Another way to write the same division is

rand()/(RAND_MAX+1.0)

Of course, you don't want to do integer division. The expression (RAND_MAX+1.0) evaluates to a double, which makes the division a double.

The function should never return exactly 1.0. A common mistake is to use this division:

(double)rand()/RAND_MAX

which returns a 1.0 approximately once every RAND_MAX times. This might seem "good enough", but it is not. For example, if you were using this function to add random noise to a digital image, approximately one pixel per 180 by 180 square of the image would be defective.

RAND_MAX is sometimes a fairly small number, depending on the C environment. Often it is only 215, which is 32768. This means that the pseudorandom values that the function returns are separated by a minimum distance of 1/32768.0 == 0.00003052 which might not be good enough for some applications.

Notice that the function is somewhat deceptive. You might think that a function called randDouble() would take advantage of the precision available with double and return values with a very fine separation. But this is not so (at least, not for the function presented here). You might want to try to write your own function that makes full use of the data type double.

The format code in the printf() is " %12.10lf". The last two characters are lower case L and F (lf, for "long float") used to designate a double precision value. The 12.10 means to use 12 columns for the number, and that 10 of those columns are for the part after the decimal point. The other two columns are for the leading zero and the decimal point. The number is preceeded by a single space.


back