Spring Semester 2002


Lab Notes Two: The warm-ups. Solutions.

Questions:

  1. Write the following mathematical expressions in Java.

    double s = s0 + v0 * t + g * t * t / 2.0;


    double G = 4 * Math.PI * Math.PI * Math.pow(a, 3) / ( P * P * (m1 + m2));

    double FV = PV * Math.pow(1 + INT / 100, YRS); 

    double c = Math.sqrt(a * a + b * b - 2 * a * b * Math.cos(gamma))

    Note that you had a few degrees of freedom regarding the types of the variables, and what this problem was testing was essentially the ability to put together an expression with constants, identifiers (variables names) and the operators we have in Java.

    It was OK to keep the variables names as given in the original formulas, even though if you were to name them in a program you would probably follow the convention by which names of functions and variables should start with lowercase.

  2. Write the following Java expressions in mathematical notation.
    dm = m * ((Math.sqrt(1 + v / c) / Math.sqrt(1 - v / c)) - 1);

    volume = Math.PI * r * r * h;

    volume = 4 * Math.PI * Math.pow(r, 3) / 3; 

  3. What is wrong with this version of the quadratic formula?
    x1 = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 * a; 
    x2 = (-b + Math.sqrt(b * b - 4 * a * c)) / 2 * a;

    The difference is the one between

    and

    Here the Java expressions are encoding the first formula (because of the property we called 'left to right associativity'). The correct expression is the second one, where a appears in the denominator, so you need to put 2 * a in parentheses

    x1 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a); 
    
    x2 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);
    to get the right formula.

  4. Give an example of integer overflow. Would the same example work correctly if you used floating-point? Give an example of a floating-point roundoff error. Would the same example work correctly if you used integers? When using integers, you would of course need to switch to a smaller unit, such as cents instead of dollars or milliliters instead of liters.

    The answer to this question is in the book. Integers cover a smaller range than floating point numbers so switching to a floating point would no longer produce an overflow.

    Roundoff errors are also explained in the book and the simplest example is

    4.35 * 100
    which prints as 434.99999999999994 or so.

    The reason for which this happens is called gradual underflow and it can result in loss of precision. Java implements the IEEE 754 standard which accepts this behaviour because overall it makes things more predictable for a certain class of numerical algorithms.

    For us in this class (A201/A597, that is) this actually won't be an issue. However if you do want infinite precision (and no range limits) you should use the classes BigInteger and BigDecimal in java.math as explained in the book. The roundoff error described above would not happen if we were to switch to 1/100's and use integers. Essentially we would be doing the roundoff correction ourselves then, as is also explained in the book.

  5. Let n be an integer and x a floating-point number. Explain the difference between
    n = (int)x;
    and
    n = (int)Math.round(x);
    For what values of x do they give the same result? For what values of x do they give different results? What happens if x is negative?

    For positive numbers casting to an int is equivalent to taking the Math.floor() while for negative numbers casting to an int becomes in essence Math.ceil(). Both functions coincide with Math.round() in only half of the cases (and always the other half).

  6. Find at least five syntax errors in the following program.
    public class WarmUpSix
    { public static void main(String[] args) 
      { System.out.print("This program adds two numbers. ), 
                    //" and ; are missing as indicated: ^ ^
        x = 5; // x needs to be declared first 
        int y = 3.5; // fractional part requires double or float 
        System.out.print("The sum of " + x + " and " + y " is: "); 
        //                                              ^ missing + above  
        System.out.println(x + y) // missing ; 
      }
    }

  7. Find at least three logic errors in the following program.
    public class WarmUpSeven 
    { public static void main(String[] args) 
      { ConsoleReader console = new ConsoleReader(System.in);
        int total = 1; // should be 0 
        System.out.println("Please enter a number:"); 
        int x1 = Integer.parseInt(console.readLine()); 
        total = total + x1; 
        System.out.println("Please enter another number:"); 
        int x2 = Integer.parseInt(console.readLine()); 
        total = total + x1; // should be x2 
        double average = total / 2; 
        // better divide by 2.0 to not lose 0.5
        System.out.println("The average of two numbers is " 
          + average); 
      }
    }

    One can easily guess what the intended purpose of the program was.

  8. Explain the difference between 2, 2.0, "2", and "2.0".

    There are four values of three types: an integer, a floating-point number (both are numbers, but of different types), and two strings. You can do arithmetic only with the numbers.

  9. Explain what each of the following two program segments computes:
    x = 2; 
    y = x + x;
    and
    s = "2";
    t = s + s; 

    The first one computes the number 4, the second one the string "22".

  10. Uninitialized variables can be a serious problem. Should you always initialize every variable with zero? Explain the advantages and disadvantages of such a strategy.

    The problem is to be aware of the initial value in a variable. If you initialize with zero you may get into trouble if you happen to use the value in that variable in a division at the denominator. But that would be about the only case when you could get into trouble.

  11. True or false? (x is an int and s is a String)

    1. Integer.parseInt("" + x) is the same as x

      Starting from the number we make it into a string which has as characters the digits of the number and then we convert that to an integer thus getting back the number we originally started from.

    2. "" + Integer.parseInt(s) is the same as s

      Starting from a string that presumably represents a number we turn that into the number that it represents. We then make it back into a string by adding the empty string in front of it in a concatenation operation.

    3. s.substring(0, s.length()) is the same as s

      Esentially we create a second string from the first one, and this second string has all characters of the first string, and although a different object it would print the same.

  12. Give two ways for converting a number to a string. What is the advantage of each of these ways?

    Concatenating the number to the empty string is my favorite way of doing it. There is another way as explained on page 79 in the book, using the toString methods. Perhaps this second method is more explicit, but why look up the name of yet another method when we can convert it on the spot using the empty string. In the end, use what you works best for you.

  13. How do you get the first character of a string? The last character? How do you remove the first character? The last character?

    We could obtain them as substrings of length one that start at position 0 and (length - 1) respectively. Removing can only be done in an indirect way, as illustrated in class.

  14. How do you get the last digit of a number? The first digit? That is, if n is 23456, how do you find out 2 and 6? Do not convert the number to a string. Hint: %, Math.log

    You either use logarithms extensively, or turn the number to a string and take the first and the last character. Here's the formula for the first and the last digit in the number (any number) but who can verify that this formula, especially the second one, is right (as it is):

    int lastDigit = n % 10; 
    
    int firstDigit = n / (int)( Math.pow( 10, 
                                          (int)( Math.log(n) / 
                                                 Math.log(10))
                                        )
                              );

  15. What is a final variable? Can you define a final variable without supplying its value?

    Variables declared as final accept only one initialization, at the time the value is declared, or later, but only once.

  16. In each line, assume that
    double x = 2.5;
    
    double y = -1.5;
    
    int m = 18;
    
    int n = 4;
    
    String s = "Hello";
    
    String t = "World"; 
    What are the values of the following expressions?

    1. x + n * y - (x + n) * y

      In every subexpression there is one term that is a double (either x or y) so all arithmetic will be floating-point.

    2. m / n + m % n

      This is (4 + 2) so the result is 6.

    3. 5 * x - n / 5

      Same as 5 * x as 4 / 5 is 0.

    4. Math.sqrt(Math.sqrt(n))

      This is the square root of 2.

    5. (int)Math.round(x)

      First we round to 3 (as a long) then we make that an int.

    6. (int)Math.round(x) + (int)Math.round(y)

      Boils down to 3 + (-1) basically.

      Note that the closest integer to -1.51 is -2 but the closest to -1.5 is -1. So this method will always round up.

    7. s + t

      Two Strings.

    8. s + n

      A String and a number.

    9. 1 - (1 - (1 - (1 - (1 - n))))

      Same as 1 - n in this particular case.

    10. s.substring(1, 3)

      Two characters, the second and the third.

    11. s.length() + t.length()

      Two numbers, each one being 6 (as the lengths of the two Strings).

Here's what you can do to obtain the answers:

frilled.cs.indiana.edu%cat Sixteen.java
public class Sixteen {
    public static void main(String[] args) {
	double x = 2.5;
	double y = -1.5;
	int m = 18;
	int n = 4;
	String s = "Hello";
	String t = "World";
	System.out.println(x + n * y - (x + n) * y); 
	System.out.println(m / n + m % n); 
	System.out.println(5 * x - n / 5); 
	System.out.println(Math.sqrt(Math.sqrt(n))); 
	System.out.println((int)Math.round(x)); 
	System.out.println((int)Math.round(x) + (int)Math.round(y)); 
	System.out.println(s + t); 
	System.out.println(s + n); 
	System.out.println(1 - (1 - (1 - (1 - (1 - n))))); 
	System.out.println(s.substring(1, 3)); 
	System.out.println(s.length() + t.length()); 
    } 
} 
frilled.cs.indiana.edu%javac Sixteen.java
frilled.cs.indiana.edu%java Sixteen
6.25
6
12.5
1.4142135623730951
3
2
HelloWorld
Hello4
-3
el
10
frilled.cs.indiana.edu%

Hope you enjoyed this set of warmups, let me know if you have any questions.


Last updated: Jan 14, 2002 by Adrian German for A201