Main content
AP®︎/College Computer Science Principles
Course: AP®︎/College Computer Science Principles > Unit 6
Lesson 2: Simulating randomnessGenerating random numbers
Have you ever flipped a coin or rolled a dice? If so, you generated a random value — and you probably used that value to make a decision.
We can also generate random values in our computer programs, and use those to make decisions and simulate natural processes.
Generating random values
Computers aren't naturally very good at randomness. Their strength is in generating predictable output by performing sequences of programmed operations. That's just about the opposite of randomness.
To generate a truly random number, a computer would need to monitor a naturally occurring non-deterministic process, like the nuclear decay of an uranium particle. That's both expensive and slow, so most personal computers do not have true random number generators.
However, computer scientists have figured out ways to generate "pseudo-random" numbers in computer software, and the pseudo-random numbers are good enough for most purposes.
Programming languages and libraries provide procedures to generate those pseudo-random numbers.
In JavaScript,
Math.random()
generates a pseudo-random number between 0 (inclusive) and 1 (exclusive). The program below displays a number generated from
Math.random()
. Press "Restart" to see how it changes each time.When called enough times,
Math.random()
will eventually generate the number 0. However, it will never generate 1. That's why we say it's "inclusive" of 0 and "exclusive" of 1. This number line visualizes all the possible generated values in blue:
What if we need a bigger number? Perhaps our program is drawing a tree and is choosing to draw it at a height from 0 to 6 feet.
We can do that by multiplying the result of
Math.random()
by 6. Try it out below.That program generates values between 0 (inclusive) to 6 (exclusive):
Generating random integers
What about limiting the random values to just integers? If we're simulating a dice roll, we don't want to end up with numbers like "1.267" or "5.431". We just want to see integers, representing each side of the die.
For this, we need to round the result using
Math.floor()
. The floor()
procedure will round the value down to the nearest integer. Try it out below. Can you generate all the possible integers in the range?
Once you restart that program enough times, you should eventually see it display all of the integers from 0 to 5:
We're very close to simulating the roll of a die, but not quite there. Our program generates the numbers 0-5, but a standard 6-sided die corresponds to the numbers 1-6:
This is an easy fix. We'll just add 1 to the rounded result, and presto, we have a dice rolling simulation!
We might find that we frequently want to generate random integers between two values. We could copy and paste the code from above... or, better, we could make our own reusable procedure!
The procedure
randomInt()
is a handy abstraction on top of Math.random()
, allowing us to generate random integers without worrying about the details:Checking random values with conditionals
Now that we know how to generate many ranges and types of random numbers, let's actually use those numbers.
We can use a conditional to check the value of a random number and select different code to execute based on the value.
For example, this code simulates a random coin flip:
if (Math.random() < 0.5) {
println("heads!");
} else {
println("tails!");
}
When we're using a conditional to check a random value, we need to make sure our condition corresponds to the chance that the event should happen. In the code above,
Math.random()
generates values from 0 to 1, so the condition checks whether the value is in the first half of that range.If we're simulating chances like "1 in 4", that's a great time to use a chained
if
/else
with the randomInt()
procedure from above:var val = randomInt(1, 4);
if (val === 1 ) {
println("1");
} else if (val === 2 ) {
println("2");
} else if (val === 3 ) {
println("3");
} else {
println("4");
}
When we're checking to make sure code like that works as expected, we can't just run it once; that will only show one value and one code path. We need to run it multiple times, making sure the computer eventually selects every possible path.
If we want even more confidence, we could run it thousands of times and verify that the distribution of code paths matches our expectations. For the code above, we'd see each path selected about 25% of the time. It wouldn't be exactly 25%, but it'd be close.
✏️ The program below simulates a Magic 8-Ball toy with 7 different responses. Change the messages to your liking and restart the program enough times to make sure all your messages get displayed.
Random numbers in pseudo-code
There's a lot of variance in the random number generation procedures across programming languages and libraries.
This pseudocode represents the common case of generating a number between
start
and end
(including both start
and end
):RANDOM(start, end)
Here's a pseudocode version of the code that generates 1 in 4 chances:
val ← RANDOM(1, 4)
IF (val = 1 )
{
DISPLAY("1")
}
ELSE IF (val = 2 )
{
DISPLAY("2")
}
ELSE IF (val = 3 )
{
DISPLAY("3")
}
ELSE
{
DISPLAY("4")
}
🙋🏽🙋🏻♀️🙋🏿♂️Do you have any questions about this topic? We'd love to answer— just ask in the questions area below!
Want to join the conversation?
- Can't we just use Math.ceil to simplified our code?
function (start,end) {
var range = start - end
Return Math.ceil(Math.random()*range) + 1
)(1 vote)- Since Math.random() return 0 inclusive and 1 exclusive it is better to use floor. Because it can contain 0, and if you round that up it is still 0.
While it cannot contain 1, so when you round down it will never be 1.
Say in your example we do randomInt(1, 4)
range is 4-1 = 3
so if random return 0, we get an output 0 x 3 = 0.
And if random return 0.99999.. we get 0.99999... x 3 = 2.9999.., which will round up to 3.
And if you have the + 1 it will be 1-4, but then the chance of getting 1 is very very small, it happens only when random outputs exactly 0.
When rounding down you will get an even distribution.(8 votes)
- What's the dofference between function and procedure? It looks like the same thing. Eg:In this article,the randomInt procedure is a function.
Thanks in advance.(2 votes)- A function works like a math function you put something in and you expect to get something out. So you expect a return value.
A procedure performs a set of instructions but won't give you a return value.
giveRandomInt() - could be a function that returns a random integer
performUpdate() - could be a procedure that updates your system(5 votes)
- Nowhere in the passage did you explain how does a computer generate a random value, you only explained how it doesn't generate them.(3 votes)
- what does it mean to pseudocode version of the code that generates 1 in 4 chances:(1 vote)
- My understanding is that the pseudocode is used to represent code without being written in code. Because its not written in code it can be translated into any code, but you can't program anything with it. So its just a guide for writing code.(2 votes)
- Does the RANDOM function in pseudo-code only produce integers?(1 vote)
- Pseudo-code does whatever we want it to. If we want the RANDOM function to return integers in a specific range, then that's what it will do. If we want the function to give a floating-point number between 0 and 1, then it can do that as well. When writing pseudo-code, just make sure it is clear what the function does, either from context or by explicitly stating it.(2 votes)
- How does the software make pseudo-random numbers?(1 vote)
- Typically, a function is applied to some seed value (often the time elapsed since the program started running), or the OS will gather entropy (randomness) from the hardware.(1 vote)
- i just opened snap! and I wasn't ready for it(1 vote)
- How do you make it where the random generator generates slower(1 vote)
- Tell me the easy summary of the lesson(0 votes)