Java Programming   Java Programming
 |Sofia Home | Content Gallery |
Home
Syllabus
Schedule
Lessons
Assignments
Resources

Lesson 4.6 Random Numbers

Producing Random Numbers

Most languages have libraries, collections of reusable functions that are used to build more complex software. Object-oriented libraries are called class libraries. In this section, you'll look at two Java classes that allow you to generate random numbers. Along the way, you'll learn about Java packages.

In languages such as C or C++, these libraries are compiled and then linked to the program's executable image during the link step [static linking] or during program loading [dynamic linking]. 

Java's class library is organized a little differently. Rather than being placed in a single file which is loaded into memory, the classes are placed in a package. A package is a group of classes that have a "special" relationship with each other.

Java Packages

When you create a package, [which we'll do later in the course], you place the package keyword and package name at the top of each file in the package, like this:

package mystuff.mybuttons;

This package is called mystuff.mybuttons, and all of the classes in this package must be stored:

  • in a subdirectory called mybuttons
  • which is contained in a subdirectory called mystuff
The mystuff subdirectory must be located in one of the directories named in the CLASSPATH environmental variable or it must be a subdirectory of the current directory.

All of the packages that are part of the core API classes--that is, any package that starts with the name java--are contained in a single, uncompressed zip file called classes.zip [in Java 1.0 or Java 1.0] or rt.jar [in Java 2].

Using the current version of the JDK, you don't have to do anything special to "point" to these built-in classes. [You do have to include the necessary package, using import, of course.] In earlier versions of the JDK, however, you had to manually set the CLASSPATH environmental variable like this [assuming you are using Windows]:

SET CLASSPATH=.;C:\jdk\lib\classes.zip

This sets the CLASSPATH environmental variables so that it points to two different directories: the current directory [.], and the zipped set of built-in Java packages [C:\jdk\lib\classes.zip], assuming you have installed the JDK into a directory called C:\jdk. If you use a version of the JDK earlier than 1.1.6, you'll have to set this variable manually.

You also have to set the CLASSPATH manually if you want to include any libraries outside of the built-in Java class libraries. If you want to use the IBM jikes compiler, for instance, or if you want to use the Java Foundation Classes for JDK 1.1. Once you set the CLASSPATH manually to include these new classes, you have to set it to include the built-in classes as well.

In this section, we want to learn how to create random numbers. It turns out that two of Java's packages can help us do that: the Math class from the java.lang package and the Random class from the java.util package.

Back to Top

The java.lang.Math Class

The java.lang.Math class contains a set of methods for basic numeric operations. All of the methods are static, so you don't need to create a Math object to use them. Instead, you just use the name of the class like this:

root = Math.sqrt(value);

You notice that the Math class is part of the java.lang package. This package is automatically loaded and referenced by your Java Virtual Machine. You don't have to add any import statments to use any of the classes contained in java.lang.

The Math class contains the normal set of methods you'd expect. For instance, Java doesn't have a exponential operator, but it does have a method named pow() that will raise any number to a power. Here's its signature:

Math.pow(double a, double b){ }

This method returns a raised to the bth power.

Another method you may commonly use is the Math.sqrt(double) method, which returns the square-root of its argument. You may also want to make use of the static final constants: Math.E and Math.PI.

Less frequently used methods [depending upon your interests, of course] include the methods for performing logarithm and trigonometric functions.

Back to Top

Math.random()

Generating random numbers in Java could not be easier; you simply call the Math.random() method like this:

double rand = Math.random();

After you've done this, the double rand will hold a number between 0.0 and 1.0. [The number will always be less than 1.0, but it may include 0.0]

The number returned by Math.random() is called a pseudorandom number, because the numbers produced by the function tend to repeat themselves after a period of time. 

A number between 0.0 and 1.0 might not seem very useful by itself, but it is easy to massage the results into a form you can use. For instance:
Rolling Dice
Suppose you wanted to simulate rolling a pair of standard six-sided dice. You would need two variables, one to represent each die. 

Then, use Math.random() to generate a random number of each die, but before storing it in the variable, manipulate it like this:

  1. Multiply the result of Math.random() by 6 because we have 6 possiblities.
  2. Because Math.random() can return 0.0, but never 1.0, add 1 to the result.
  3. Because each die must have an integer value, cast the result to an int.

Here's what these steps look like in code:

int d1 = (int) (Math.random() * 6) + 1;
int d2 = (int) (Math.random() * 6) + 1;
Back to Top

The java.util Package

The java.util package is a collection of useful miscellaneous classes that manipulate dates and times and provide facilities for basic data structures as well as a complete random-number generating class.

To use the classes in java.util, you must import that package, unlike the classes included in java.lang. For the homework assignment for this unit, you'll work with the java.util.Date class, which represents numeric time, [that is, dates and times that can be added, subtracted, and otherwise manipulated].

As with numbers, formatting dates and times in human readable form is not really part of the basic concept of dates. The same moment in time, represented as a number, can be displayed in different ways depending upon the calendar in use.

To facilitate this translation between human [cultural] conventions and the "raw-facts" of dates and times, the java.util package provides the Calendar class that provides generic functionality. The generic Calendar, however, is of limited use; it defines what needs to be done, but can't perform the work itself. [Such classes are called abstract classes, and you'll study them in Lesson 13.]

Java's java.util package also includes a concrete implementation of a Calendar, the GregorianCalendar class. The Gregorian calendar is the calendar that is used throughout much of the world today. [We're using it, for instance, to establish the deadlines for this class.] Your text has more information on using the GregorianCalendar class.

The Random Class

Using the java.util.Random class is not quite as easy as using the Math.random() method. First, of course, you have to import the java.util package. You don't have to do that to use the methods in the Math class. Second, you must create a Random object. The methods of the Random class are not static like those of the Math class.

Despite this extra work, however, creating a Random object, and using its methods to generate your random numbers, can often prove beneficial. Let's start by creating a Random object.

Back to Top

Creating Random Objects

When you construct a Random object you have your choice of two Random constructors: one that takes no argument and one that takes a single long as the random number generator seed.

Random r1 = new Random();
Random r2 = new Random(10L);

If you use the first constructor, the seed used for the random number generator is taken from the current time. If you use the second constructor, the numbers generated will be randomly distributed, but the same sequence will always repeat in exactly the same order, every time the program is run. 

This is often useful for testing. You run the program using a predefined seed during the test phase, and then switch to a more truly random seed when you ship your product.

Generating Numbers

To generate a random number, you send messages to your Random object, asking it to manufacture a new number for you. Here are some of the random numbers you can ask for:
  • nextDouble() returns a double between 0.0 and 1.0. This method has exactly the same characteristics as calling Math.random()
  • nextFloat() works like nextDouble() but the result is a float.
  • nextInt() and nextLong() return an int and a long, repectively, that is uniformly distributed over the entire range of int or long. That means, nextInt() could return a number anywhere from two-billion to minus two-billion.
  • nextGaussian() returns a double like nextDouble(), but rather than being uniformly distributed, the number is "the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence."
Once you've generated a random number using one of these methods, you have to manipulate it, as you did earlier, to make sure it falls within the range of acceptable values. 

Because the return values are a little different, the manipulations are also. For instance:
Pick-Six
Suppose you wanted to simulate an extremely hard-to-win lottery game called Pick-Six, where the winner must guess six random numbers between 1 and 50.

This time, let's use the java.util.Random class, and the nextInt() method to generate our numbers. As with the dice rolling example, you'll need some variables to store each of the six picks. Then, use the nextInt() method to generate a random number of each pick, but before storing it in the variable, manipulate it like this:

  1. Because the random number can be positive or negative, use Math.abs() to convert it to a positive number.
  2. Once it is a positive number, you need to restrict it to the values 1 to 50. Do that by using the mod [%] operator.
  3. The result of using % 50 will be a positive number from 0-49, so you have to add 1 for your final answer.

Here's what these steps look like in code:

Random r = new Random();
int p1 =(Math.abs(r.nextInt()) % 50)+1;
int p2 =(Math.abs(r.nextInt()) % 50)+1;
int p3 =(Math.abs(r.nextInt()) % 50)+1;
int p4 =(Math.abs(r.nextInt()) % 50)+1;
int p5 =(Math.abs(r.nextInt()) % 50)+1;
int p6 =(Math.abs(r.nextInt()) % 50)+1;

Something to Talk About

Here are some review questions to make sure you understand the material in this section. What do you think?
  1. What directory is the ActionEvent class, passed as an argument used in the actionPerformed() method, located in? [Hint; you can tell from the package you must import]
  2. Write a line of code that generates a random number, using Math.random(), for a human temperature that is within  +/- 5 degrees of 98.6 degrees Fahrenheit.
  3. Write a line of code that generates a random number, using the nextInt() method in the Random class that picks a year from the 20th century [1900-1999].

This is the last section of this lesson.

 

Back to Top

 

Content Developed by Stephen Gilbert, Licensed under a Creative Commons License
Published by the Sofia Open Content Initiative
© 2004 Foothill-De Anza Community College District &The William and Flora Hewlett Foundation