Universidad Carlos III de Madrid

Ingeniería de Telecomunicación

Enero-Mayo 2010 / January-May 2010

Recap: Fundamentals of Java

Lab Section1.  Session 2 (lab): Review exercises

We advise the students to program according to usual Java conventions. The document Java Coding Guidelines presents a brief introduction to the most important conventions, as well as instructions on how to configure Eclipse according to them.

Exercise Section1.1.  Debugging Java programs with Eclipse: Calculation of pi

A debugger is a program to test other programs in a controlled way. A debugger allows finding errors in programs (bugs) and help to understand them.

Common functionalities of a debugger:

  • Run a program step by step (this is, the program will execute one source code statement and then wait for further instructions).

  • Stop the execution of a program at a given line of source code and wait for further user instructions.

  • Allow to inspect the values of the program variables while its execution is stopped.

The Eclipse IDE includes a nice Java debugger that can help you to find and fix bugs in your programs.

Section 1: A program to compute pi

The following program computes the value of pi with the desired precision (the number of desired decimal places is passed as a command argument).

import java.math.BigDecimal;
import java.math.MathContext;

public class PiCalc {

    private int numDigits;
    private MathContext mc;

    public PiCalc(int numDigits) {
        this.numDigits = numDigits;
        mc = new MathContext(numDigits);
    }

    public BigDecimal compute() {
        BigDecimal pi = new BigDecimal(0);
        BigDecimal limit = new BigDecimal(1).movePointLeft(numDigits);
        boolean stop = false;
        for (int k = 0; !stop; k++) {
            BigDecimal piK = piFunction(k);
            pi = pi.add(piK);
            if (piK.compareTo(limit) < 0) {
                stop = true;
            }
        }
        return pi.round(mc);
    }

    private BigDecimal piFunction(int k) {
        int k8 = 8 * k;
        BigDecimal val1 = new BigDecimal(4);
        val1 = val1.divide(new BigDecimal(k8 + 1), mc);
        BigDecimal val2 = new BigDecimal(-2);
        val2 = val2.divide(new BigDecimal(k8 + 4), mc);
        BigDecimal val3 = new BigDecimal(-1);
        val3 = val3.divide(new BigDecimal(k8 + 5), mc);
        BigDecimal val4 = new BigDecimal(-1);
        val4 = val4.divide(new BigDecimal(k8 + 6), mc);
        BigDecimal val = val1;
        val = val.add(val2);
        val = val.add(val3);
        val = val.add(val4);
        BigDecimal multiplier = new BigDecimal(16);
        multiplier = multiplier.pow(k);
        BigDecimal one = new BigDecimal(1);
        multiplier = one.divide(multiplier, mc);
        val = val.multiply(multiplier);
        return val;
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("One command-line argument expected: number of "
                               + "digits.");
        } else {
            PiCalc piCalc = new PiCalc(Integer.parseInt(args[0]));
            System.out.println(piCalc.compute());
        }
    }
}

Take a look at its source code without paying too much attention to its details and answer the following questions.

  • Can you describe the program flow? This is, what methods are invoked and in which order? Is there any method that is being executed more than once?

  • Justify why the class BigDecimal is used instead of the native Java types float or double. Look for external documentation to back up your answer.

Section 2: Running the program

Import the program into Eclipse and run it several times with varied precisions. Note how the program takes more and more time to execute as you ask for higher precisions (in the next section you will understand why is that).

Section 3: Using the Eclipse debugger

Use the Eclipse debugger to understand how the program works. Set a breakpoint in the first line of the method compute() (menu Run / Toggle Breakpoint). Run the program in debug mode, using Debug instead of Run. The program will begin its execution and will stop at your breakpoint.

You will be asked to change the Eclipse perspective to the Debugging Perspective, which will allow you to control and obtain information about the ongoing debugging session. You will be able to see your source code, along with a marker on the line that is going to be executed next. You can also see the values of your program variables (at first, only this is shown, which is the object with the method where the breakpoint is; if you unfold it, you will be able to see the values of all its attributes). You can also see the Console.

Now that the program is waiting at the breakpoint, you can resume its execution in several ways:

  • Option Run / Resume: resume the program execution until it finishes or until a breakpoint is reached.

  • Option Run / Step Into: execute the next line of code. If this line is a method invocation, the program will stop executing at the first line of code inside that method, so you can execute the program step by step.

  • Option Run / Step Over: execute the next line of code. If this line is a method invocation, the program will execute the whole method normally and then stop once it returns. This is very useful to understand the general flow of the program without getting into the details of each method.

  • Option Run / Step Return: execute the code in the current method until it gets to a return statement.

You can also cancel the debugging mode by using the option Run / Terminate.

Debug the program using 10 as its command line argument. Count the number of iterations performed on the loop inside the method compute() before getting the final value of pi. Repeat this for bigger arguments. What can you say about the time it takes to execute the program as a function of its argument?

In a new debugging session, keep track of the value of the variable piK on each loop iteration. How is this value changing with each iteration of the loop?

What is the role of the limit variable in the program? Run additional debugging sessions if you need to.

Section 4: The expression to calculate pi

What is the mathematical expression that the program is using to calculate the value of pi? You can answer this question by thinking about the source code above and using the debugger.

Section 5: Area of a circle

Write a new Java program to calculate the area of a circle knowing it radius. This program will have a main method that will receive as its arguments the decimal places of pi for the calculation of the solution and the radius of the circle. The program must write the calculated area to its standard output.

The program must use the class PiCalc presented above to generate a suitable value of pi for its calculations. It must also use the class BigDecimal.

Section 6: Total area of several circles

Write a new Java program to calculate the sum of the areas of several circles, knowing their radii. The program will have a main method with the following arguments: the desired precision on pi and one or more radii values (one per circle). The program must write the solution to the standard output.

This program must use the class from the previous section and BigDecimal.