Choosing Random Numbers

Flash ActionScript 2.0

NOTE:  This article has been updated here, due to errors discovered by NSurveyor.

ActionScript 1.0 and 2.0 provide two ways to pull a random number from thin air:  the random() function and the static Math.random() method.  Of these, the random() function is the older (available since Flash 4) and is the “easier to use,” according to a number of developers.  But keep in mind, it’s not the officially recommended way to go. 

random()

The function works like this:  say you want a random number between one and ten, including either extreme.  The function returns an integer value between zero and one less than the supplied parameter, so if you want your number to be among the set 1, 2, 3, …, 10, then pass in ten and add one to the result.

var rand:Number = random(10) + 1;

There you have it.  The rand variable now contains an integer between (possibly including) one and ten.  How does that work, again?  The function returns a value between zero and one less than the supplied parameter, so supplying ten return any number in the set 0, 1, 2, …, 9, which added to one gives you the range you want.

Okay.  Well and good.  But the random() function was deprecated as of Flash 5.  That means it’s still “legal” to use, but the official recommended best practice is to use Math.random() instead.

Note:  Practically speaking, in all these years, I’ve only seen support dropped for a single deprecated term, but it does happen.  Long ago, you could concatenate strings with the add operator, but Flash Player 8 and higher no longer support the practice.  Any SWFs out there that still use add — who knows how many there are? — simply fail when the Player hits that operator, provided those SWFs are viewed in Flash Player 8 or higher.

Math.random()

This is a static method, which means you don’t reference a class instance when calling it; you reference the class name itself.  Math.random() returns a non-integer value between zero and one.  That’s right, zero and one — including possibly zero (which, I suppose, would be an integer; okay, okay, there’s always an exception!).  If you want a random number between one and ten in this case, you’ll have to multiply the return value by nine, round the answer down, then add one to the result.  Sounds complicated, I realize, but let’s see it in action.

var rand:Number = Math.round(Math.random() * 9) + 1;

Let’s see what’s going on, here, working from the inside out.  At the very center, Math.random() provides a number between zero and one (including, possibly zero).  Typical results might be any of the following …

0.568371209315956
0.186107741203159
0.643053698353469
0.542485995218158
0.771115215960892

… note that zero even is simply not a likely result.

Multiplied by nine, the above list might be any of these:

7.05780873075128
2.09764451393858
8.10042055277154
0.43995537701994
6.56350261252373

This expression, Math.random() * 9, is run through Math.round() to crunch those floats into integers.  Finally, this combined expression, Math.round(Math.random() * 9), is added to one, to bump everything up a notch.  Zeroes become ones, ones twos, etc., and nines become tens.  Thus the desired range of “between one and ten” is achieved.

Ranges outside the set “between one and …”

What if you want a random number between -5 and 5?  Easy enough.  The above approach hints toward a generic formula that provides the answer.  Take a look at this custom function:

function randomRange(min:Number, max:Number):Number {
  return Math.round(Math.random() * (max - min + 1)) + min;
}

The inner expressions have changed a bit, but the principle is the same.  The difference between the upper end lower ends, plus one, provide the value to multiply with Math.random().  Instead of adding one to the result, add min (because the lower end may not be one).

Flipping a coin

Heads or tails?  To determine a random number between one and two, simply round the return value of Math.random().  But do yourself a favor and think in terms of the double meanings certain numbers have.  In ActionScript (and most programming languages), one and zero correspond neatly to true and false.  Actually, technically speaking, zero corresponds to false and any other number corresponds to true, but it’s easy to remember one and zero.

The expression Math.round(Math.random()) returns either 1 or 0.  Use it to answer any yes-or-no question randomly!

11 Responses to “Choosing Random Numbers”

  1. NSurveyor Says:

    I was just about to comment about how sometimes people mess up the distribution of the randomness until I realized you, David, have made the same mistake! A lot of the above code is flawed. You are not getting even distribution where you are using Math.round()!

    var rand:Number = Math.round(Math.random() * 9) + 1);

    Math.round(Math.random()*9+1) is not evenly distributed. Consider when that value is:

    1…
    0<=Math.random()*9<0.5.

    For values, x, greater than 1 and less than 10…
    x-0.5<=Math.random()*9<x+0.5.

    10…
    8.5<=Math.random()*9<9.

    As you can see, the two ends, 1 and 10 are half as likely to occur with the above code. We can also show this experimentally:

    var x = [0,0,0,0,0,0,0,0,0,0];
    for(var i=0;i<1000;i++){
    var r = Math.round(Math.random() * 9+1)-1;
    x[r]++;
    }
    trace(x);

    To remedy, use Math.floor (or ceil):

    var rand:Number = Math.floor(Math.random()*10+1)
    or even
    Math.floor(Math.random()*10)+1

    The same applies to your between code (which also can exceed the max by 1!). The correct code is:

    function randomRange(min:Number, max:Number):Number {
    return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    Besides that, you can manipulate the randomness to get say either a 1 or -1:

    Math.floor(Math.random())*2-1

    In fact, I’ve seen this used several times in the forums… like Byron Canfield, Laiverd.COM, and I’m quite sure kglad has used it as well.

  2. David Stiller Says:

    NSurveyor,

    Ahh, man! Thank you. :-D For real, thanks for that input! As soon as I hit the Publish button on this post, a thought flitted across my brain. The thought said, “Hey, wait a minute … the lowest and highest numbers are only half as likely to be chosen …” — and you’ve already pointed out the issue in detail, as well as the correction.

    I hate to admit it, but I was simply too tired (yes, even at 9PM!) to go back and rethink/rewrite the post. But I should have. You’re absolutely right.

    Humble pie makes a good meal.

  3. Denis Ivanov Says:

    This has been infinitely helpful, I thoroughly appreciate both your efforts. I am just sure a lot more of us starting web developers applaud bits like this, so I express this on behalf of all those who didn’t have time to.

    Thank You.

  4. David Stiller Says:

    Denis,

    Thanks! Glad to hear you enjoy the content. In the case of this particular article, make sure you read the updated companion piece.

  5. Gs Says:

    Suppose, If my first five numbers are 88,73,95,68,55 Between 1 to 100.
    What will be possible next 5 numbers for me…..??

  6. David Stiller Says:

    Gs,

    If the next five numbers are random, then they would be five numbers between (or including) 1 and 100.

  7. Gs Says:

    David,

    Yeah Next five numbers also random number between 1 to 100…but
    what are that possible numbers…
    Is there any equation or formula to find next 5 numbers by calculating
    or using given five numbers…

  8. David Stiller Says:

    Gs,

    Yeah Next five numbers also random number between 1 to 100…but what are that possible numbers…

    Didn’t we cover this? ;)

    Is there any equation or formula to find next 5 numbers by calculating or using given five numbers…

    Sure. :) If you can think of an equation to generate a specific sequence of numbers, it can almost certainly be codified in ActionScript 2.0. But by definition, then, the sequence wouldn’t be random, so maybe I’m misunderstanding your question.

  9. NSurveyor Says:

    I think I know what Gs is getting at.

    I recall in True BASIC, if you tried using random calls without “randomize” you would get the same numbers every time you ran the program.

    When you think about it, how is it possible to generate a truly random number? AFAIK, they aren’t… rather they are pseudorandom numbers. I believe the algorithm uses a timer and some complex mathemetical formula.

    If for example, the “mathematical formula” were a simply a polynomial, then we can determine the polynomial and all subsequent “random” numbers, given one more than the degree of the polynomical. Example, if random tells us f(0) = 2, f(1) = 3, f(2) = 6, we can determine that f(x) = x^2+2, assuming we are dealing with a 2nd degree polynomial. And then generate the random numbers manually.

    But anyways, I think the algorithm would be too complex to foretell the random numbers, nor would there ever be an opportunity to exploit it.

  10. Tim Says:

    Yes, thanks for taking the time to write this. I wrote a yahtzee game using math.round and I noticed 1’s and 6’s were hard to get, and thus the distribution at the upper and lower bounds of my range were 1/2 as likely to occur.

    Thanks for all the contributions!!!

  11. David Stiller Says:

    Tim,

    You’re welcome! :) Glad to help.

Leave a Reply