Skip to main content
Logo image

Section 3.3 The Math class

Luckily we don’t have to write all the methods we might need ourselves. Java comes with a rich library of methods that we can use. (In fact we’ve been using a few of these methods already, print and println. We’ll explain in a later lesson what the System.out part is about.)
In a future lesson we’ll talk about how to explore the library of methods that come with Java. For now we want to look at one particular set of methods that are useful for doing math beyond the basic arithmetic we can do with the arithmetic operators we’ve already learned about.
As we learned in the ChapterΒ 1Β Introduction, all code in Java is written within classes. There’s a lot to say about classes and we’ll get to it in later units. But some classes just exist as a place to put a bunch of useful methods. One such class is the Math class in the java.lang package which is part of every Java program. (We’ll also learn more about packages in later units.)
The Math class contains five methods that are in the AP CSA subset and are listed in the AP CSA Java Quick Reference Sheet that you will have access to during the exam.
There are more Math methods, outside of what you need on the AP exam, that you can find in the Math class Javadocs.

Subsection 3.3.1 The mathematical functions

Of these Math methods, abs, pow, and sqrt are true mathematical functions that compute new values from their arguments.
Math.abs is an example of an overloaded method meaning there are two methods with the same name but different signatures: one that takes an int and one that takes a double. They each return the absolute value, i.e. the positive value of the number without its sign, of their argument. But the return type of each method also differs, being the same same as the type of the parameter.
Math.abs(45);    // returns 45
Math.abs(-45);   // returns 45
Math.abs(33.3);  // returns 33.3
Math.abs(-33.3); // returns 33.3
Math.pow takes two arguments, both doubles and returns a double which is the first argument raised to the power of the second argument. I.e. pow(a, b) is what we would write in math as \(a^b\text{.}\) But because ints can be silently converted to doubles, we can call Math.pow with int arguments and they will automatically be converted to doubles. As a result, the return value will always be a double even if it could be represented by an int.
Math.pow(2 , 3); // returns 8.0, not 8
Math.pow(10, 6); // returns 1000000.0, not 1000000
Math.pow(2, -3); // returns 0.125

Note 3.3.1.

If you are a Desmos or graphical calculator user, note that ^ is not an exponentiation operator in Java. Worse luck, it is an operator on ints but it does something completely different. So if a and b are ints and you write a ^ b, intending to raise a to the bth power, the compiler won’t complain but your code will do something very different. If you want an int result, use a cast: (int) Math.pow(a, b). Though watch out for overflow errors since even relatively small exponents can produce values greater than Integer.MAX_VALUE.
Math.sqrt takes an double argument and returns a double value which is the nearest approximation of the positive square root of the argument. As with Math.pow, we can call it with an int argument but the argument will be converted to a double and the result will always be a double even if it could have been represented with an int.
Math.sqrt(2); // returns 1.4142135623730951
Math.sqrt(9); // returns 3.0, not 3
Since these methods are all non-void methods, calling them only makes sense in a context that will do something with the value they return, such as assigning the value to a variable or printing it out.
System.out.println("The square root of 9 is " + Math.sqrt(9));

Activity 3.3.1. Try some math.

Try the Math methods below. Change the code so that it computes the absolute value of -4, the square root of 9, and 3 raised to the power of 2.

Activity 3.3.2. Legal call to sqrt.

Knowing that Math.sqrt takes a single argument, Which of these are syntactically correct method calls to sqrt?
  • Math.sqrt(2)
  • βœ… This is a simple call to Math.sqrt with the argument 2.
  • Math.sqrt()
  • ❌ Math.sqrt takes one argument. This would be a correct call if it took no arguments.
  • Math.sqrt(2, 4)
  • ❌ Math.sqrt takes one argument. This would be a correct call if it took two arguments.
  • Math.sqrt(2 + 3)
  • βœ… The argument passed to Math.sqrt is the value of the expression 2 + 3, namely 5.
  • Math.sqrt 2
  • ❌ You must have parentheses around the arguments.
  • Math.sqrt(Math.sqrt(2))
  • βœ… The argument passed to Math.sqrt is the value of another call to Math.sqrt which is perfectly fine.

Activity 3.3.3. Distance.

The distance between two numbers on the number line is defined as the absolute value of their difference. Their difference is just what you get when you subtract one from the other. For example, the distance from 0 to 3 is 3, the distance from -3 to 0 is 3, and the distance from -3 to 1 is 4.
number line
Which of the following are correct expressions to compute the distance between the numbers a and b.
  • Math.abs(a - b)
  • βœ… a - b gives us the difference and Math.abs gives us the absolute value of that difference.
  • Math.abs(a) - Math.abs(b)
  • ❌ Consider the distance between -2 and 3. It should be five. What value would this expression produce in that case?
  • Math.abs(a + b)
  • ❌ We need to start with the difference between a and b, not their sum.

Activity 3.3.4. Distance method.

Using the definition of distance from the previous problem, fill in the method distance below so it correctly computes the distance between two numbers a and b.

Subsection 3.3.2 Random numbers

Dice
Games would be boring if the same thing happened each time you played the game. And many simulation techniques, including those used to train Large Language Models like ChatGPT, depend on generating random variations. The key to making games interesting and to running useful simulations is the ability to generate random numbers. The Math.random() is the simplest way to get random numbers in Java.
Math.random() is not a function in the mathematical senseβ€”it doesn’t return the same value every time it is called with the same arguments. In fact, it doesn’t even take any arguments. But every time we call it we will get a double greater than or equal to 0.0, and less than 1.0. For all practical purposes the number we get each time is random and all numbers that can be represented by a double between zero and one are equally likely.

Activity 3.3.5. Test Math.random.

Run the following code several times to see what it prints each time.

Note 3.3.3.

When we talk about ranges of numbers sometimes we need to be precise about whether the ends of the range are part of the range. For example, loosely speaking we might say that Math.random returns a number between zero and one. But does that mean it can return exactly 0.0? Or exactly 1.0? As it turns out it can return 0.0 but never returns 1.0.
When we need to be precise about this we’d say that it returns a number between zero, inclusive, and one, exclusive, meaning include zero but exclude one. Lots of ranges in Java are expressed this way, as you’ll see later on with an inclusive bottom and exclusive top.
Getting a number in the range from zero to one, may not seem all that useful by itself. But we can expand the range easily enough. To see how, imagine you had less than a dollar to your name and you wanted to be richerβ€”you’d want to find a way to multiply your money. If you could invest every penny you had in something that would multiply your money by 1,000 then instead of having somewhere between $0 and $1, then you’d have somewhere between $0 (inclusiveβ€”if you started with $0) and $1,000 (exclusive, since if you had even a fraction of a penny less than $1 multiplying by 1,000 would still leave you just a bit shy of $1,000.) If the investment multiplied your original money by a million, you’d have between $0 and $1,000,000! (But never quite $1,000,000.)
Same trick applies to random numbers. The value Math.random returns is like the initial amount of money in your pocket, always a bit less than $1. If you multiply that value by any amount, it will stretch it into the range you want:

Activity 3.3.6. Multiplied random numbers.

Try the following code. Run it several times to see what it prints each time. Did you ever see 0.0? How about 1.0?
You may have noticed that while the numbers generated were always in the range 0 to 10, all the numbers probably had a lot a digits after the decimal point. Often we want a random integer, with nothing after the decimal point. Easy enoughβ€”casting a double to an int will throw away any values after the decimal point. For example,
// rnd will be an integer in the range 0-9 (from 0 up to 10).
int rnd = (int) (Math.random() * 10);
Finally, what if we want a number in a range that doesn’t start with 0, say a number from 1 to 10 (including 10) instead of from 0 to 9 (including 9)? Since the size of the two ranges is the same, with ten numbers in each, all we need to do is shift from the range we’ve generated into the range we want. In other words, add the difference between the two ranges, 1 in this case.
// rnd will be an integer in the range 1-10 (including 10).
int rnd = (int) (Math.random() * 10) + 1;

Activity 3.3.7. Random ints.

Run the code below several times to see how the value changes each time. How could you change the code to return a random integer from 1 to 10? Modify the code and see if your answer is correct. Try removing the parentheses from around (Math.random() * 10) and run the code several times. What happens? The parentheses are necessary because (int) will cast the closest expression, and (int)Math.random() will always be 0 since anything after the decimal point is dropped.
Here are some examples that move a random number into a specific range.
// Math.random() returns a random number between 0.0 (inclusive) and 1.0 (exclusive)
double rnd = Math.random();

// rnd1 is an integer in the range 0-9 (including 9).
int rnd1 = (int) (Math.random() * 10);

// rnd2 is in the range 1-10 (including 10).
int rnd2 = (int) (Math.random() * 10) + 1;

// rnd3 is in the range 5-10 (including 10). The range is 10-5+1 = 6.
int rnd3 = (int) (Math.random() * 6) + 5;

// rnd4 is in the range -10 up to 10 (including 10). The range is doubled (10 - -10 + 1 = 20) and the minimum is -10.
int rnd4 = (int) (Math.random() * 21) - 10;
So the general recipe for generating a random is to first stretch the value from Math.random() until it’s in a range of the right size by multiplying by the size of the range. Then if we want an integer value, cast to int to discard the part after the decimal point. Then shift the value up by adding the minimum value. The table below shows some applications of that general recipe.
Table 3.3.4.
Expression Minimum (inclusive) Maximum (exclusive) Possible values
Math.random() 0.0 1.0 Over 9 quadrillion
Math.random() * 100 0.0 100.0 Over 9 quadrillion
(int) (Math.random() * 100) 0 100 100
(int) (Math.random() * 50) + 25 25 75 50
(int) (Math.random() * max) 0 max max
(int) (Math.random() * range) + min min min + range range
(int) (Math.random() * (max - min)) + min min max max - min

Activity 3.3.8. Random number 1-5.

Which of the following would return a random number from 1 to 5 inclusive?
  • (int) (Math.random() * 5)
  • This would be a number between 0 and 4.
  • (int) (Math.random() * 6)
  • This would be a number between 0 and 5.
  • (int) (Math.random() * 5) + 1
  • The first part would return a number between 0 and 4 and adding 1 produces a number from 1 to 5, inclusive.

Activity 3.3.9. Random number 0-10.

Which of the following would return a random number from 0 to 10 inclusive?
  • (int) (Math.random() * 10)
  • This would be a number between 0 and 9.
  • (int) (Math.random() * 11)
  • This would be a number between 0 and 10.
  • (int) (Math.random() * 10) + 1
  • The first part would return a number between 0 and 9 and adding 1 produces a number from 1 to 10, inclusive.

Activity 3.3.10. Random number 25-60.

Which of the following expressions always evaluates to a random integer between 25 and 60, inclusive?
  • (int) (Math.random() * 25) + 36
  • Remember that (int) (Math.random() * size) + min takes random numbers in the range 0-size to a new range starting at min. We want the minimum number to be 25, but the minimum number here would be 36.
  • i(int) (Math.random() * 25) + 60
  • Remember that (int) (Math.random() * size) + min takes random numbers in the range 0-size to a new range starting at min. We want the minimum number to be 25, but the minimum number here would be 60.
  • (int) (Math.random() * 26) + 60
  • Remember that (int) (Math.random() * size) + min takes random numbers in the range 0-size to a new range starting at min. We want the minimum number to be 25, but the minimum number here would be 60.
  • (int) (Math.random() * 36) + 25
  • Yes, (int) (Math.random() * 36) + 25 takes random numbers in the range from 0-36, exclusive, into the range 25-60 (inclusive). The range is (max number - min number + 1) which is (60 - 25 +1) = 36.
  • (int) (Math.random() * 60) + 25
  • This would give us random numbers from 25 to 85. Remember that you can compute the range you need with (max number - min number + 1).

Subsection 3.3.3 Coding challenge: Combo lock

lock
You may have a combination lock on your locker at school where you have to spin the dial to three separate numbers from 0 up to 39, inclusive. What if you forgot your combination? Would you be able to guess it?
  1. Write code that will generate 3 random integers from 0 up to 40 (but not including 40) using Math.random() in the Active Code window below. Run it a couple times to see it generate different numbers.
  2. How many times would you need to run it to guess your combination correctly? Let’s have the code compute the number of permutations possible in your combination lock using Math.pow(number, exponent). For example, if you had to spin the dial twice on your combination lock where each spin can choose a digit from 0-9 (10 digits), there are \(10^{2}\) possible permutations. In Java, this would be written as Math.pow(10, 2) which means 10 to the power of 2. If you start listing all the permutations possible, you can tell that there are \(10^{2}\) or 100 possible permutations for a 2 spins on a dial lock from 0-9.
    00, 01, 02, 03, 04, 05, 06, 07, 08, 09
    10, 11, 12, 13, 14, 15, 16, 17, 18, 19
    ...
    90, 91, 92, 93, 94, 95, 96, 97, 98, 99
    
Now what about the combination lock for this challenge? You will need to spin the dial 3 times: once to the right, once to the left, and once to the right to three different numbers from 0 up to 40 (not including 40). In general, the formula to use is \(n^{s}\) where \(n\) is the number of numbers on the dial and \(s\) is the number of spins. Write this using the Math.pow() method in your code and save it into a variable and print out.

Project 3.3.11. Combo locks.

Complete the combination lock challenge below.

Subsection 3.3.4 Coding Challenge: Dancing turtles

Random turtle drawing
Here’s another challenge that is a lot of fun! Can you use random numbers to make dancing turtles? This idea was suggested by CSA teacher Zac Martin.

Project 3.3.12. Dancing turtles.

Complete the random numbers using Math.random() in the correct ranges to choose x, y coordinates and a random color by choosing random red, green, and blue values in the range of 0-255. Put on some music and watch your turtle dance!

Subsection 3.3.5 Coding Challenge: Tower ladder

Ladder on tower
The Pythagorean theorem states that the length of the hypotenuse (the side opposite the right angle in a right triangle) is the square root of the sum of the squares of the lengths of the other two sides, also called the β€œlegs” or the width and height of the triangle. Here’s the formula for this theorem: \(c = \sqrt{a^{2} + b^{2}}\) where \(a\) and \(b\) are the width and height of the triangle and \(c\) is the length of the hypotenuse.
This may seems like a bunch of Greek to you but one common, real-world use for the Pythagorean theorem is to calculate the length of ladder you will need to reach the window of your beloved, given that their cruel parents have locked them in a tower surrounded by a moat. The ladder will be the hypotenuse of a triangle whose legs are the height of the window of your beloved’s room in the tower and the width of the moat since you have to place the base of the ladder on the edge of the moat.

Activity 3.3.13. Find correct hypotenuse.

Which of the following are correct Java expressions to compute the hypotenuse of a triangle with legs a and b given the Pythagorean Theorem \(c = \sqrt{a^{2} + b^{2}}\) where \(a\) and \(b\) are the lengths of the legs and \(c\) is the length of the hypotenuse?
  • Math.sqrt(a * a + b * b)
  • βœ… a * a is a squared, likewise b * b. Adding them with + gives us the sum which is then passed to Math.sqrt.
  • Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))
  • βœ… Math.pow(a, 2) is a squared, likewise Math.pow(b, 2). Adding them with + gives us the sum which is then passed to Math.sqrt.
  • Math.sqrt(a + b)
  • ❌ Close, but we need to square the lengths of the legs.
  • a * a + b * b
  • ❌ This is the sum of the squares of the lengths of the legs which gives us the square of the hypotenuse. We need a Math.sqrt to get the length of the hypotenuse.

Project 3.3.14. Ladder size.

Complete the ladderSizeNeeded method below using the Pythagorean Theorem and the Math.sqrt method. Then in the main method, write a method call to test the ladderSizeNeeded method with arguments for the height of 30 and the width of 40. The method should return the length of the ladder needed to reach the window of your beloved.

Activity 3.3.15. Vocab check.

Subsection 3.3.6 Summary

  • (AP 1.10.A.2) Class methods are typically called using the class name along with the dot operator. When the method call occurs in the defining class, the use of the class name is optional in the call.
  • (AP 1.11.A.1) The Math class is part of the java.lang package. Classes in the java.lang package are available by default.
  • (AP 1.11.A.2) The Math class contains only class (static) methods. They can be called using Math.method(); for each method.
  • (AP 1.11.A.2) The following static Math methods are part of the Java Quick Reference:
    • int abs(int) : Returns the absolute value of an int value (which means no negatives).
    • double abs(double) : Returns the absolute value of a double value.
    • double pow(double, double) : Returns the value of the first parameter raised to the power of the second parameter.
    • double sqrt(double) : Returns the positive square root of a double value.
    • double random() : Returns a double value greater than or equal to 0.0 and less than 1.0 (not including 1.0)!
  • (AP 1.11.A.3) The values returned from Math.random() can be manipulated to produce a random int or double in a defined range.
  • (int)(Math.random() * range) + min moves the random number into a range starting from a minimum number. The range is the (max - min + 1). For example, to get a number in the range of 5 to 10, use the range 10-5+1 = 6 and the min number 5: (int)(Math.random()*6) + 5.
You have attempted of activities on this page.