2.1   Static Methods


The Java construct for implementing functions is known as the static method.

Using and defining static methods.

The use of static methods is easy to understand. For example, when you write Math.abs(a-b) in a program, the effect is as if you were to replace that code by the value that is computed by Java's Math.abs() method when presented with the value a-b. If you think about what the computer has to do to create this effect, you will realize that it involves changing a program's flow of control.

Properties of static methods.

Functions.java gives a number of examples.
Function examples
Gaussian distribution function and cumulative distribution function

Implementing mathematical functions.

We now consider two important functions that play an important role in science, engineering, and finance. The Gaussian (normal) distribution function is characterized by the familiar bell-shaped curve and defined by the formula:
Gaussian pdf
and the cumulative Gaussian distribution function Φ(z) is defined to be the area under the curve defined by φ(x) above the x-axis and to the left of the vertical line x = z. For example, Φ(1.96) = 0.975. This means that 97.5% of the area under the standard Gaussian curve is to the left of z = 1.96. Gaussian.java implements both of these static methods.

Using static methods to organize code.

With the ability to define functions, we can better organize our programs by defining functions within them when appropriate. For example, Coupon.java is a version of CouponCollector.java that better separates the individual components of the computation. Whenever you can clearly separate tasks in programs, you should do so.

Arrays as arguments and return values.

A static method can take an array as an argument or as a return value.

Superposition of sound waves.

Notes like concert A have a pure sound that is not very musical, because the sounds that you are accustomed to hearing have many other components. Most musical instruments produce harmonics (the same note in different octaves and not as loud), or you might play chords (multiple notes at the same time). To combine multiple sounds, we use superposition: simply add their waves together and rescale to make sure that all values stay between 1 and 1.
Superposition of sound waves
PlayThatTuneDeluxe.java is a version of PlayThatTune that encapsulates the sound wave calculation and adds harmonics. Here a few sample data files (created by various students):
Flow of control of static methods


Q + A

Q. Why do I need to use the return type void? Why not omit the return type?

A. Java requires it; we have to include it. Second-guessing a decision made by a programming-language designer is the first step to becoming one.

Q. Can I return from a void function by using return. If so, what return value should I use?

A. Yes. use the statement return; with no return value.

Q. What happens if I leave out the keyword static?

A. As usual, the best way to answer a question like this is to try it yourself and see what happens. Non-static methods are different from static methods. You will learn about them in Chapter 3.

Q. What happens if I write code after a return statement?

A. Once a return statement is reached, control immediately returns to the caller, so any code after a return statement is useless. The Java compiler identifies this situation as an error, reporting unreachable code.

Q. What happens if I do not include a return statement?

A. No problem, if the return type is void. In this case, control will return to the caller after the last statement. When the return type is not void, the compiler will report a missing return statement error if there is any path through the code that does not end in a return.

Q. The issue with side effects and arrays passed as arguments is confusing. Is it really all that important?

A. Yes. Properly controlling side effects is one of a programmers most important tasks in large systems. Taking the time to be sure that you understand the difference between passing a value (when arguments are of a primitive type) and passing a reference (when arguments are arrays) will certainly be worthwhile. The very same mechanism is used for all other types of data, as you will learn in Chapter 3.

Q. So why not just eliminate the possibility of side effects by making all arguments pass-by-value, including arrays?

A. Think of a huge array with, say, millions of elements. Does it make sense to copy all of those values for a static method that is just going to exchange two of them? For this reason, most programming languages support passing an array to a function without creating a copy of the array elements—Matlab is a notable exception.

Exercises

  1. Write a static method max3() that takes three int values as arguments and returns the value of the largest one. Add an overloaded function that does the same thing with three double values.
    public static int max3(int a, int b, int c) {
       int max = a;
       if (b > max) max = b;
       if (c > max) max = c;
       return max;
    }
    
    public static double max3(double a, double b, double c) {
       double max = a;
       if (b > max) max = b;
       if (c > max) max = c;
       return max;
    }
    
  2. Write a static method odd() that takes three boolean inputs and returns true if an odd number of inputs are true, and false otherwise.
  3. Write a static method majority() that takes three boolean arguments and returns true if at least two of the arguments have the value true, and false otherwise. Do not use an if statement. Solution: here are two solutions: the first is concise; the second strictly adheres to the rules.
    public static boolean majority(boolean a, boolean b, boolean c) {
       return (a && b) || (a && c) || (b && c);
    }
    
    public static boolean majority(boolean a, boolean b, boolean c) {
       while (a && b) return true;
       while (a && c) return true;
       while (b && c) return true;
       return false;
    }
    
  4. Write a static method eq() that takes two arrays of integers as arguments and returns true if they contain the same number of elements and all corresponding pairs of elements are equal, and false otherwise.

    Solution. ArraysEquals.java.

  5. Write a static method areTriangular() that takes three double values as arguments and returns true if they could be the sides of a triangle (none of them is greater than or equal to the sum of the other two). See Exercise 1.2.15.
  6. Write a static method sigmoid() that takes a double argument x and returns the double value obtained from the formula: 1 / (1 + e^-x).
  7. If the argument of sqrt() in Newton.java has the value Infinity, then Newton.sqrt() returns the value Infinity, as desired. Explain why.
  8. Add a method abs() to Newton.java, change sqrt() to use abs() instead of Math.abs(), and add print statements to produce a function call trace, as described in the text. Hint : You need to add an argument to each function to give the level of indentation.
  9. Give the function call trace for java Newton 4.0 9.0.
  10. Write a static method lg() that takes a double value N as argument and returns the base 2 logarithm of N. You may use Java's Math library.
  11. Write a static method lg() that takes an int value N as argument and returns the largest int not larger than the base-2 logarithm of N. Do not use Math.
  12. Write a static method signum() that takes an int value N as argument and returns -1 if N is less than 0, 0 if N is equal to 0, and +1 if N is greater than 0. (See also the static method Integer.signum().)
  13. Consider the following static method duplicate() below.
    public static String duplicate(String s) {
       String t = s + s;
       return t;
    }
    
    What does the following code fragment print out?
    String s = "Hello";
    s = duplicate(s);
    String t = "Bye";
    t = duplicate(duplicate(duplicate(t)));
    StdOut.println(s + t);
    
  14. Consider the static method cube() below.
    public static void cube(int i) { 
       i = i * i * i; 
    } 
    
    How many times is the following for loop iterated?
    for (int i = 0; i < 1000; i++) 
       cube(i); 
    
    Answer: see textbook.
  15. The following checksum formula is widely used by banks and credit card companies to validate legal account numbers:

    d0 + f(d1) + d2 + f(d3) + d4 + f(d5) + d6 + ... = 0 (mod 10)
    
    The di are the decimal digits of the account number and f(d) is the sum of the decimal digits of 2d (for example, f(7) = 5 because 2 * 7 = 14 and 1 + 4 = 5). For example, 17327 is valid because 1 + 5 + 3 + 4 + 7 = 20, which is a multiple of 10. Implement the function f and write a program to take a 10-digit integer as a command-line argument and print a valid 11-digit number with the given integer as its first 10 digits and the checksum as the last digit.
  16. Given two stars with angles of declination and right ascension (d1, a1) and (d2, a2), the angle they subtend is given by the Haversine formula:
    2 arcsin((sin^2(d/2) + cos (d2) * cos(d1) * sin^2(a/2)^1/2), 
    
    where a1 and a2 are angles between -180 and 180 degrees, d1 and d2 are angles between -90 and 90 degrees, a = a2 - a1, d = d2 - d1. Write a program to take declination and right ascension of two stars as command-line arguments and print the angle they subtend. Hint: Be careful about converting from degrees to radians.

    See also Exercise 1.2.33. Latitude corresponds to declination and longitude to ascension.

  17. Write a readBoolean2D() method that reads a two-dimensional boolean matrix (with dimensions) into an array. Answer: see textbook.
  18. Write a method that takes an array of double values as argument and rescales the array so that each element is between 0 and 1 (by subtracting the minimum value from each element and then dividing each element by the difference between the minimum and maximum values). Use the max() method defined in the table in the text, and write and use a matching min() method.
  19. Write a method histogram() that takes an array a[] of int values and an integer M as argument and returns an array of length M whose ith entry is the number of times the integer i appeared in the argument array. If the values in a[] are all between 0 and M-1, the sum of the values in the returned array should be equal to a.length.
  20. Assemble code fragments in this section and in Section 1.4 to develop a program that takes N from the command line and prints N five-card hands, separated by blank lines, drawn from a randomly shuffled card deck, one card per line using card names like Ace of Clubs.
  21. Write a method multiply() that takes two square matrices of the same dimension as arguments and produces their product (another square matrix of that same dimension). Extra credit: Make your program work whenever the number of rows in the first matrix is equal to the number of columns in the second matrix.
  22. Write a method any() that takes an array of boolean values as argument and returns true if any of the entries in the array is true, and false otherwise. Write a method all() that takes an array of boolean values as argument and returns true if all of the entries in the array are true, and false otherwise.
  23. Develop a version of getCoupon() that better models the situation when one of the coupons is rare: choose one value at random, return that value with probability N /1000, and return all other values with equal probability. Extra credit: How does this change affect the average value of the coupon collector function?
  24. Modify PlayThatTune.java to add harmonics two octaves away from each note, with half the weight of the one-octave harmonics.

Creative Exercises

  1. Birthday problem. Develop a class with appropriate static methods for studying the birthday problem (see Exercise 1.4.35).
  2. Euler's totient function. Euler's totient function is an important function in number theory: φ(n) is defined as the number of positive integers less than or equal to n that are relatively prime with n (no factors in common with n other than 1). Write a function that takes an integer argument n and returns φ(n), and a main() that takes an integer from the command line, calls the function, and prints the result.
  3. Harmonic numbers. Write a program Harmonic that contains three static methods H(), Hsmall(), and Hlarge() for computing the Harmonic numbers. The Hsmall() method should just compute the sum (as in Harmonic.java), the Hlarge() method should use the approximation H(N) = N = log_e(N) + γ + 1/(2N) - 1/(12N^2) + 1/(120N^4) (the number γ = .577215664901532... is known as Euler's constant), and the H() method should call Hsmall() for (N < 100) and Hlarge() otherwise.
  4. Gaussian random values. Experiment with the following method for generating random variables from the Gaussian distribution, which is based on generating a random point in the unit circle and using a form of the Box-Muller transform. (see Exercise 1.2.27 and the discussion of do-while at the end of Section 1.3).
    public static double gaussian() {
       double r, x, y;
       do {
          x = uniform(-1.0, 1.0); 
          y = uniform(-1.0, 1.0); 
          r = x*x + y*y;
       } while (r >= 1 || r == 0);
       return x * Math.sqrt(-2.0 * Math.log(r) / r);
    }
    

    Take a command-line argument N and generate N random numbers, using an array a[20] to count the numbers generated that fall between i*.05 and (i+1)*.05 for i from 0 to 19. Then use StdDraw to plot the values and to compare your result with the normal bell curve.

    Remark: This method is preferred over the one described in Exercise XYZ for both efficiency and accuracy. Although it involves a loop, the do-while loop is executed only 4 / π = 1.273 times on average. This reduces the overall expected number of calls to transcendental functions.

  5. Binary search. A general method that we study in detail in Section 4.2 is effective for computing the inverse of a cumulative probability density function like Phi(). Such functions are continuous and nondecreasing from (0, 0) to (1, 1). To find the value x0 for which f(x0) = y0, check the value of f(.5). If it is greater than y0, then x0 must be between 0 and .5; otherwise, it must be between .5 and 1. Either way, we halve the length of the interval known to contain x0. Iterating, we can compute x0 to within a given tolerance. Add a method PhiInverse() to Gaussian.java that uses binary search to compute the inverse.

    Change main() to take a number p between 0 and 100 as a third command-line argument and print the minimum score that a student would need to be in the top p percent of students taking the SAT in a year when the mean and standard deviation were the first two command-line arguments.

  6. Black-Scholes option valuation. The Black Scholes formula supplies the theoretical value of a European call option on a stock that pays no dividends, given the current stock price s, the exercise price x, the continuously compounded riskfree interest rate r, the standard deviation σ of the stock's return (volatility) and the time (in years) to maturity t. The value is given by the formula

    Black Scholes

    where

    Black Scholes

    Write a program BlackScholes.java that takes s, x, r, sigma, and t from the command line and prints the Black-Scholes value.

    Myron Scholes won the 1997 Nobel Prize in Economics for the Black-Scholes paper.

  7. Implied volatility. Typically the volatility is the unknown value in the Black-Scholes formula. Write a program that reads s, x, r, t, and the current price of the option from the command line and uses binary search (see Exercise 2.1.29) to compute σ.
  8. Horner's method. Write a class Horner.java with a method double eval(double x, double[] p) that evaluates the polynomial p(x) whose coefficients are the entries in p[]:
    p0 + p1x1 + p2x2 + ... + pN-2xN-2 + pN-1xN-1 
    
    Use Horner's method, an efficient way to perform the computations that is suggested by the following parenthesization:
    p0 + x (p1 + x( p2 + ... + x(pN-2 + xpN-1))...)
    
    Write a test client with a static method exp() that uses Horner.eval() to compute an approximation to e^x, using the first N terms of the Taylor series expansion e^x = 1 + x + x 2/2! + x 3/3! + .... Include code to check your answer against that computed by Math.exp().
  9. Benford's law. The American astronomer Simon Newcomb observed a quirk in a book that compiled logarithm tables: the beginning pages were much grubbier than the ending pages. He suspected that scientists performed more computations with numbers starting with 1 than with 8 or 9, and postulated the first digit law, which says that under general circumstances, the leading digit is much more likely to be 1 (roughly 30%) than the digit 9 (less than 4%). This phenomenon is known as Benford's law and is now often used as a statistical test. For example, IRS forensic accountants rely on it to discover tax fraud. Write a program Benford.java that reads in a sequence of integers from standard input and tabulates the number of times each of the digits 1-9 is the leading digit, breaking the computation into a set of appropate static methods. Use your program to test the law on some tables of information from your computer or from the web. Then, write a program to foil the IRS by generating random amounts from $1.00 to $1,000.00 with the same distribution that you observed.

    The file princeton-files.txt is a list of file sizes on a public Unix machine at Princeton.

  10. Binomial distribution. Write a function public static double binomial(int k, int N, double p) to compute the probability of obtaining exactly k heads in N biased coin flips (heads with probability p) using the formula
                         N! 
        f(k, N, p) = --------- (p^k) ((1-p)^(N-k)) 
                     k! (N-k)! 
    
    Hint: To stave off overflow, compute x = ln f(N, k, p) and then return e^x. In main(), take N and p from the command line and check that the sum over all values of k between 0 and N is (approximately) 1. Also, compare every value computed with the normal approximation f(N, k, p) = φ(Np, Np(1-p))

    (see Exercise 2.2.1).

  11. Coupon collecting from a binomial distribution. Develop a version of getCoupon() that uses binomial() from the previous exercise to return coupon values according to the binomial distribution with p = 1/2. Hint : Generate a uniformly distributed random number x between 0 and 1, then return the smallest value of k for which the sum of f (N, j, p) for all j < k exceeds x. Extra credit : Develop a hy- pothesis for describing the behavior of the coupon collector function under this assumption.
  12. Chords. Develop a version of PlayThatTune.java that can handle songs with chords (including harmonics). Develop an input format that allows you to specify different durations for each chord and different amplitude weights for each note within a chord. Create test files that exercise your program with various chords and harmonics, and create a version of Fur Elise that uses them.
  13. Postal bar codes. The POSTNET barcode used by the U.S. Postal System to route mail is defined as follows: Each decimal digit in the zip code is encoded using a sequence of three half-height and two full-height bars. The barcode starts and ends with a full-height bar (the guard rail) and includes a checksum digit (after the five-digit zip code or ZIP+4), computed by summing up the original digits modulo 10. Implement the ollowing functions
    • Draw a half-height or full-height bar on StdDraw.
    • Given a digit, draw its sequence of bars.
    • Compute the checksum digit.
    and a and a test client that reads in a five- (or nine-) digit zip code as the command-line argument and draws the corresponding postal bar code.
    Value 0 1 2 3 4 5 6 7 8 9
    Encoding ||╷╷╷ ╷╷╷|| ╷╷|╷| ╷╷||╷ ╷|╷╷| ╷|╷|╷ ╷||╷╷ |╷╷╷| |╷╷|╷ |╷|╷╷
  14. Calendar. Write a program Calendar.java that takes two command-line arguments m and y and prints out the monthly calendar for the mth month of year y, as in this example:
       February 2009
     S  M Tu  W Th  F  S
     1  2  3  4  5  6  7
     8  9 10 11 12 13 14
    15 16 17 18 19 20 21
    22 23 24 25 26 27 28
    

    Hint: See LeapYear.java and Exercise 1.2.29.

  15. Fourier spikes. Write a program that takes a command-line argument N and plots the function Plot (cos(t) + cos(2t) + cos(3t) + cos(4t) + ... + cos(Nt)) / N for 500 equally spaced samples of t from -10 to 10 (in radians). Run your program for N = 5 and N = 500. Note: You will observe that the sum converges to a spike (0 everywhere except a single value). This property is the basis for a proof that any smooth function can be expressed as a sum of sinusoids.

Web Exercises

  1. Diamond tile. Write a program DiamondTile.java that takes a command-line argument N and creates an N-by-N tile of diamonds. Include static methods diamond() and filledDiamond().
  2. Hexagonal tile. Write a program HexTile.java that takes a command-line argument N and creates an N-by-N tile of hexagons. Include static methods hexagon() and filledHexagon().
  3. Inverse Gaussian cumulative distribution. Suppose SAT math scores are normally distributed with mean 500 and standard deviation. Estimate how high student must score in order to be among the top 10%. To do this you need to find the value z for which Φ(z, 500, 100) = 0.9. Hint: use binary search.
  4. SAT scores. A prominent northeastern university receives 20,000 student applications. Assume that the SAT scores of these individuals is normally distributed with mean 1200 and standard deviation 100. Suppose the university decides to admit the 5,000 students with the best SAT scores. Estimate the lowest score that will still be admitted.
  5. Voting machines. Suppose that in a population of 100 million voters, 51% vote for candidate A and 49% vote for candidate B. However, the voting machines are prone to make mistakes, and 5% of the time they produce the wrong answer. Assuming the errors are made independently and at random, is a 5% error rate enough to invalidate the results of a close election? What error rate can be tolerated?
  6. Gambler's histogram. Write a program RandomWalk.java that takes one command line parameter M and simulates a gambler starting with M who places exactly M one dollar bets.
    1. Produce a histogram of the amount of money the gambler ends up with by running this experiment N times.
    2. The amount of money the gambler ends up with follows a binomial distribution with mean M and variance N/4. The distribution can be approximated by a normal distribution with the same mean and variance. Produce a histogram for the fraction of time you'd expect the gambler to end up with the amount in each histogram bin.
    Organize your program up into several functions.
  7. Statistical sampling. Write a program Sampling.java takes a random sample of N people and asks them a yes/no question. Compute a 95% confidence interval.
  8. Blackjack. Write a program Blackjack.java that plays the basic strategy or write a program BlackjackCounter.java that implements the high-low card counting system.
  9. Wavelets. Applications to computer vision, human vision, speech processing, compressing the FBI fingerprint database, filtering noisy data, detecting self-similarity in time series, sound synthesis, computer graphics, medical imaging, analyzing the clumping of galaxies, and analyzing turbulence. The Haar function is definite by Φ(x) = 1 if 0 ≤ x < 1/2, Φ(x) = -1 if 1/2 ≤ x < 1, and Φ(x) = 0 otherwise. For integer m and n, the Haar basis function Φm,n(x) = 2-m/2 Φ(2-mx - n). Write a program Haar.java that takes two integer input M and N, and one real input x and prints Φm,n(x). Or maybe plot it?
  10. Baccarat. Baccarat is a simple card game which has been romanticized in James Bond movies. When the player is dealt nine, the croupier proclaims "neuf a la banque". Write a program that determines your chance of winning....
  11. Collinear points. Write a function
    public boolean areCollinear(int x1, int y1, int x2, int y2, int x3, int y3)
    

    that returns true if the three points (x1, y1), (x2, y2), and (x3, y3) lie on the same line, and false otherwise.

  12. Gauss error function. The error function is a function that arises in probablity, statistics, and solutions to differential equations. For example, Φ(z) = 1/2 + (1 + erf(z / sqrt(2))), where Φ(z) is the Gaussian cumulative distribution function defined above.
    Error function

    The integral has no closed form solution in terms of elementary functions so we resort to approximations. When z is nonnegative, the Chebyshev fitting estimate below is accurate to 7 significant digits:

    Chebyshev approximation to error function

    If z is negative, use the identity erf(z) = -erf(-z). A particularly efficient way to implement it is via a judicious use of parentheses known as Horner's method. Write a function erf() in ErrorFunction.java takes one real input z and computes the error function using the formula above.

  13. Haversine. Write a function haversine() that takes one double argument θ and returns haversine(θ) = (sin(θ/2))^2.
  14. Soil temperature. (Cleve Moler) Suppose the soil temperature is uniformly Ti (20 degrees C) at the surface and beneath. A cold front moves in and the surface temperature Ts (-15 C) remains for the foreseeable future. The temperature T(x, t) at time t seconds of the soil at x meteres beneath the surface is given by T(x, t) = Ts + (Ti - Ts) erf(x / 2 sqrt(alpha t)), where alpha (0.138 * 10^-6 m^2 / s) is the thermal conductivity of the soil. What is the temperature at 10 meters after 30 days of exposure to these conditions? How long until water freezes (0 degrees) at 5 meters beneath the surface? How deep to dig a water main so that it can withstand 60 days of exposure to these conditions without freezing?
  15. Implied volatility of Black-Scholes. The volatility parameter sigma is often unknown. Suppose you know the price of a call option whose underlying asset has current price S, strike price X, time to maturity T, and interest rate r. Determine the implied volatility by solving the Black-Scholes formula for sigma. There is no closed form solution, so use binary search. You can use repeated doubling or halving to find appropriate values of sigma_min and sigma_max to bracket the true value.
  16. Craps. Calculate the probability of winning a pass bet in craps. Here are the rule for a pass bet. Roll two 6-sided dice, and let x be their sum.
    • if x is 7 or 11, you win instantly
    • if x is 2, 3, or 12, you lose instantly
    • otherwise, repeatedly roll two dice until their sum is either x or 7
      • if their sum is x, you win
      • if their sum is 7, you lose

    Program Craps.java takes a command line parameter N and simulates N pass bets. The program's organization benefits from two helper functions: sumOfTwoDice and winsPassBet. Both functions have one interesting feature - they do not take any input arguments. The first function simulate the throw of two dice. This returns an integer between 2 and 12, but not all values are equally likely. To simulate the probabilities correctly, we call StdRandom.random(6) twice and one to generate a number between 1 and 6. Then, we add the two values. The second function returns a boolean value: true if we win the pass bet and false otherwise. This function has several return statements. As soon as the first one is executed, the function terminates with the given return value.

  17. Musical scale. Using the function note(), write a program Scale.java to play a major scale.
  18. Primality testing. Create a function isPrime() that takes an integer argument N and returns true or false depending on whether N is prime.
    public static boolean isPrime(long N) {
       if (N < 2) return false;
       for (long i = 2; i*i <= N; i++) {
          if (N % i == 0) return false;
       }
       return true;
    }
    
  19. Electronic funds transfer routing number check. Given a 9 digit EFT routing number a1a2a3a4a5a6a7a8a9 the check equation is
    3 a1 + 7a2 + a3 + 3a4 + 7a5 + a6 +3a7 +7a8 +a9 mod 10 = 0
    Check digit reference.
  20. Write a static method nint() that takes a real number as a parameter and returns the nearest integer. Do not use any Math library function, instead use casting.
  21. Write a static method int mod(int a, int n), where a is an integer and n is a positive integer, and returns a mod n. This corresponds to a % n when a is positive, but if a is negative, a % n returns a nonpositive integer.
  22. Present value.
    1. Write a method fv that computes the amount of money you will have if you invest C dollars today at the compound interest rate of r per period, in T periods. The formula for the future value is given by C*(1 + r)^T.
    2. Write a method pv that computes the amount of money that would have to be invested now, at the compound interest rate r per period, to obtain a cash flow of C in T periods. The formula for the present value is given by C/(1 + r)^T.
  23. The ACT is another standardized test. Assume that test scores follow a Gaussian distribution with mean 18 and standard deviation 6. Also assume that the test takers for SAT and ACT are indistinguishable. Which is better, an SAT score of 620 or ACT of 26?
  24. Write a program Factorial.java that takes one integer command line input n and prints out n! = 1 * 2 * ... * n. Write a function that has the following signature:
    public static long factorial(int n)
    

    What is the largest value of n that your function can handle without overflow?

  25. What is wrong with the following function?
    static int sum(int n) {
        if (n < 0) return;
        double sum = 0.0;
        for (int i = 0; i < n; i++)
           sum = sum + i;
        return sum;
    }
    

    Answer: The function is declared to return a value of type int. The first return statement is wrong since it returns nothing. The second return statement is wrong since it returns a value of type double.

  26. What does the following do?
    public static void negate(int a) {
        a = -a;
    }
    
    public static int main(String[] args) {
        int a = 17;
        System.out.println(a);
        negate(a);
        System.out.println(a);
    }
    

    Answer: It prints 17 twice. A function cannot change the value of a primitive type variable in another function.

  27. Write a function that takes three real arguments, x, y, and s, and plots an equilateral triangle centered on (x, y) with side length s. Call the function a number of times in main to produce an entertaining pattern.
  28. Which of the following functions returns the minimum of its four inputs? Which is easiest to understand and verify that it is correct?
    public static int min(int a, int b, int c, int d) {
       // if a is the smallest return it
       if (a <= b && a <= c && a <= d) return a;
    
       // otherwise, if b is the smallest of b, c, and d, return it
       if (b <= c && b <= d) return b;
    
       // otherwise, return the smaller of c and d
       if (c <= d) return c;
       return d;
    }
    
    public static int min(int a, int b, int c, int d) {
       int min = a;
       if (b < min) min = b;
       if (c < min) min = c;
       if (d < min) min = d;
       return min;
    }
    
    public static int min(int a, int b, int c, int d) {
       if (a < b && a < c && a < d) return a;
       if (b < c && b < d)          return b;
       if (c < d)                   return c;
       return d;
    }
    
    public static int min(int a, int b, int c, int d) {
       if (a <= b) {
          if (a <= c) {
             if (a <= d)  return a;
             else return d;
          }
          if (c <= d) return c;
          else return d;
       }
       if (b <= c) {
          if (b <= d) return b;
          else return d;
       }
       else if (c <= d) return c;
       return d;
    }
    
    public static int min(int a, int b) {
       if (a <= b) return a;
       else        return b;
    }
    public static int min(int a, int b, int c, int d) {
       return min(min(a, b), min(c, d));
    }
    

  29. How would you go about testing whether one of the functions in the previous exercise does what it claims to do?

    Answer: you can't hope to test it on every conceivable input since there are 2128 different possible inputs. Instead, test it on all 4! = 24 cases depending on whether a < b, a < c, ..., c < d. Or all 4^4 permutations of 0, 1, 2, and 3.

  30. What's wrong with the following method call?
    double y = 2.0;
    double x = sqrt(double y);
    

    It re-declare the variable y when calling sqrt().

  31. Sawtooth. Write a program SawTooth.java to plot 2/pi [sin(1t)/1 + sint(2t)/2 + sin(3t)/3 + ... ]. As you plot more and more terms, the wave converges to a sawtooth wave. Then play it using standard audio.
  32. Square wave. Plot 4/pi [sin(1*2*pi*t)/1 + sint(3*2*pi*t)/3 + sin(5*2*pi*t)/5 + ... ]. As you plot more and more terms, the wave converges to a square wave. Then play it using standard audio.
  33. Write a program to print the lyrics to Old McDonald.
    public static String sing(String animals, String sound) {
       String s = "";
       s += "Old MacDonald had a farm\n";
       s += "E-I-E-I-O\n";
       s += "And on his farm he had some " + animals + "\n";
       s += "With a " + sound + "-" + sound + " here\n";
       s += "And a " + sound + "-" + sound + " there\n";
       s += "Here a " + sound + ", there a " + sound + "\n";
       s += "Everywhere a + sound + "-" + sound + "\n";
       s += "Old MacDonald had a farm\n";
       s += "E-I-E-I-O\n";
       return s;
    }
    ...
    System.out.println(sing("chicks", "cluck"));
    System.out.println(sing("cows",   "moo"));
    System.out.println(sing("pigs",   "oink"));
    System.out.println(sing("cats",   "meow"));
    System.out.println(sing("sheep",  "baa"));
    System.out.println(sing("ducks",  "quack"));
    System.out.println(sing("horses", "neigh"));
    
  34. Write a static method maxwellBoltzmann() that returns a pseudo-random value from a Maxwell-Boltzmann distribution with parameter σ. To produce such a value, take the sum of the squares of three Gaussian random variables with mean 0 and standard deviation σ, and return the square root. The speeds of molecules in an ideal gas have a Maxwell-Boltzmann distribution, where the parameter σ is related to XYZ.
  35. Write a static method reverse1() that takes a string array as an argument and creates a new array with the entries in reverse order (and does not change the order of the entries in the argument array). Write a static method reverse2() that takes a string array as an argument and reverses its entries. Put your code in a program Reverse.java.
  36. Which function gets called by f(1, 2) if I have two overloaded functions
    public static void f(int x, double y) {
       System.out.println("f(int, double)");
    }
    
    public static void f(double x, int y) {
       System.out.println("f(double, int)");
    }
    

    Solution. Ordinarily, Java's type promotion rules would promote either int argument to double. However, in this case, that would result in two matching overloaded signatures. Since Java can't resolve the ambiguity, Overloaded.java results in a compile-time error.