Finreir has asked for the wisdom of the Perl Monks concerning the following question:

When I run this code, the results for $randomx and $randomy are constant (after 1 or 2 iterations) , but if I remove the "/ 6075", I have a pseudo random number generator. Why ?
#!/usr/bin/perl -w use strict; my $randomx=37; # the seed for x my $randomy=1531; # the seed for y my $n_randomx=0; my $n_randomy=0; my $i=0; while ($i<101) { $n_randomx=(($randomx*106+1283) % 6075) / 6075; $n_randomy=(($randomy*106+1283) % 6075) / 6075; print "$i $randomx $randomy\n\n"; $randomx=$n_randomx; $randomy=$n_randomy; $i++; }

Replies are listed 'Best First'.
Re: Division Problem
by Roy Johnson (Monsignor) on Apr 28, 2005 at 17:32 UTC
    Convergence. The division (coupled with the modulus) ensures that your number is between 0 and 1 after one iteration. Then it's going to be effectively (1283 + something less than 106)/6075. Pretty soon, the something-less-than-106 converges on a value that goes in and comes out unchanged. Solve for x=(x*106 + 1283)/6075.

    Caution: Contents may have been coded under pressure.
Re: Division Problem
by Transient (Hermit) on Apr 28, 2005 at 17:09 UTC
    When your randomx or randomy gets below some number where x*106 < 1, then you'll always get 1283.xxxx - which when modded with 6075 will always give you 1283, which, when divided, will give you the same answer.

    Oh, and your pseudo-random number generator repeats... after 6075 iterations :)
Re: Division Problem
by sh1tn (Priest) on Apr 28, 2005 at 17:26 UTC
    Sample random number generator -
    my $min = 10000; my $max = 100000-$min+1; srand; for( 1..100 ){ print int rand($max)+$min, $/ }


Re: Division Problem
by ww (Archbishop) on Apr 28, 2005 at 18:19 UTC

    Roy Johnson's is correct in response to the question your asked and Transient's reply looks "right" but it's his last line and shltn's reply that address a fundamental fallacy in your $var_names and the language of your description of your problem (note, ++, that your title is "bang on" for the first part of your question.)

    Simply put, your script provides NOelement of randomness other than the inappropriate naming of the variables; "inappropriate" because they do NOT describe the variables with anything resembling what they actually contain).

    Every value is either defined or deterministic. Look at your code:
    my $randomx=37; # the seed for x 005: my $randomy=1531; # the seed for y
    The only process that changes those assignments occurs below (inside the while loop) at (abbreviated):
    $n_randomx=(($randomx*106+1283) % 6075) / 6075; ... $randomx=$n_randomx;

    which is to say, the next iteration is different from the last only in that it uses the latest (ie, "predictable" or "deterministic" $n_randomx, assigned to $randomx, to set the starting point for the next iteration.

    There is simply no way to achieve "randomness" nor even pseudo-randomness, by multipling, dividing, dividing-modulus, adding or subtracting a fixed and restricted set of numbers (which is another way to say "defined or deterministic numbers".

    And while your output may look, to you, "random" after you've removed the divide-by-6075, it isn't. Again, the output remains the same for each run, and worse, with a fairly modest effort, a mathemetician, cryptographer or the like could easily use a comparatively small segment of your output to ascertain your input.

    That said, the output may be sufficiently varied to satisfy some purpose you have, but you had best NOT use it to "secure" anything ... and you'll do yourself a favor, long term, to avoid naming variables using words that suggest their contents are something they're not. At best you'll confuse some future user or maintainer, and at worst, confuse yourself.

Re: Division Problem
by tlm (Prior) on Apr 29, 2005 at 01:26 UTC

    Why are you dabbling at writing your own PRNG? This is one of those areas where "angels fear to tread." It's hard to write a good PRNG, even for experts. Commenting on the notorious rand() of the C standard library, the authors of Numerical Recipes in C (p. 276, 2nd ed.) write:

    If all scientific papers whose results are in doubt because of bad rand()s were to disappear from library shelves, there would be a gap on each shelf about as big as your fist.

    the lowliest monk

Re: Division Problem
by Finreir (Initiate) on Apr 29, 2005 at 08:16 UTC
    Ok, I really have to thanks everybody for your answers, I now understand my mistake (stupid mistake : In fact I wanted a number between 0 and 1 ....). But I have to answer some stuffs :

    First I'am not trying to build my own random number generator (I know the rand() perlfunction), I'am just trying this one which is named (I also know that it is not truly random) linear congruential method. I'am trying this one, because it IS deterministic and because it is widely used for Monte Carlo simulation (I'am not trying cryptography stuffs ....).

    Second, one usefull and simple test of a random generator is to break a sequence of random numbers int blocks of k numbers, which are taken to be coordinates in a k-dimensional space. A good random number should give a random distribution of points, the linear congruential method (with good parameters) seems to give good results, and I wanted to see .... (I'am gonna try it to with the rand() for fun to!)

    Third : Here's the formula : u1=seed ui=MOD{(ui-1 x a + b),m}

    Fourth : Next step Marsaglia Random Number Generator !
Re: Division Problem
by hubb0r (Pilgrim) on Apr 29, 2005 at 05:13 UTC
    You've already gotten great answers to your question, but I have a question for you:

    Why not just use rand()?