## Lab 5 In-Class: Exploring Data Representation & Conditional (if) Statements

### Lab Objectives

• Experience the problem of overflow; gain an understanding of why it happens and how to recognize it.
• Gain more experience with casting and widening data conversions.
• Gain experience in using if statements.

Log onto the Linux system and create a lab5 subdirectory of your cs120/Labs directory for today's work. As usual, you will need to have three windows open: an xterm, Eclipse, and Firefox.

### What is your age in seconds?

The file Age.java contains the skeleton of a Java application that will take as input a person's age in years, months, and days and then compute and print the age in seconds.
1. Complete the program as follows:
• immediately AFTER the "define conversion constants" commment declare a conversion constant SECONDS_PER_DAY and in the initialization have the computer do the arithmetic (in other words you shouldn't get out your calculator and figure out how many seconds are in a day -- write the expression so the computer has to do the work)
• define other constants and/or variables as needed (assume there are 30 days in a month and 365 days in a year) - note that some variables have already been declared
• calculate and print, appropriately labeled, the total number of seconds (place your code where indicated by the comments!!)

Test your program. For example, a person who is 18 years, 3 months, and 21 days old has lived 577,238,400 seconds (under the assumptions of the program). A person who is 21 years, 0 months, and 0 days has lived 662,256,000 seconds.

2. How many seconds has a person who is 68 years, 6 months, and 12 days old lived? Run your program to find out.

You should have gotten a strange answer to the last question! Why did your program produce such an answer? Hint: Java uses a 32-bit two's complement representation for type int. So do the following to see what's going on:

• Compute the largest int value that Java can represent - write out the formula and find its value (you can check your answer by looking in the textbook on page 46).
• Now look at the other ages in seconds you have computed, e.g., 21 years. 68 years is a little over triple that value. So, what is the problem with 68 years? Why did you get such a strange answer?

3. Fix your program as follows:
• Change the type of one variable from int to long, which is a 64-bit integer representation. Think about which variable is going to contain a number too big for 32 bits - don't just randomly change! It should work to change only ONE variable (unless you declared lots of other variables and did several intermediate calculations). Your program should still work exclusively with integers, not floating point numbers.
• The above change will not completely solve the problem (run your program and see). You need to make sure the expression is computed using the larger data type - a carefully placed cast operator should do the trick! (NOTE: You should be able to correct this with just one variable type change and one cast; however, the order in which you do calculations may require more.)

Test the program again and make sure it works. A person who has lived 68 years, 6 months, and 12 days is 2,161,036,800 seconds old. Also try 99 years, 9 months, and 9 days and make sure the answer makes sense.

### A Base Conversion Program

In class we learned an algorithm for converting a base 10 number to another base by repeatedly dividing by the base. Each time a division is performed the remainder and quotient are saved. At each step, the number used in the division is the quotient from the preceding step. The algorithm stops when the quotient is 0. For example to convert the base 10 number 1878 to base 8 you would do the following:
Quotient      Remainder
1878 divided by 8 -->     234             6
234 divided by 8 -->      29             2
29 divided by 8 -->       3             5
3 divided by 8 -->       0             3

The number in the new base is the sequence of remainders in reverse order (the last one computed goes first; the first one goes last). In this example, the base 8 answer is 3526 (that is 187810 = 35268). In this exercise you will use this algorithm to write a program that converts a base 10 number to a 4-digit number in another base (you don't know enough programming yet to be able to convert any size number). The base 10 number and the new base (2 - 9) will be input to the program. The start of the program is in the file BaseConvert.java. Open the file in Firefox, save it to your lab5 subdirectory, then open it in Eclipse. Modify the program one step at a time as follows:
1. The program will only work correctly for base 10 numbers that fit in 4 digits in the new base. We know that in base 2 the maximum unsigned integer that will fit in 4 bits is 11112 which equals 15 in base 10 (or 24 - 1). In base 8, the maximum number is 77778 which equals 4095 in base 10 (or 84 - 1). In general, the maximum unsigned base 10 number that fits in 4 base b digits is b4 - 1. Add an assignment statement to the program to compute this value for the base that is input and assign it to the variable maxNumber. Add a statement that prints out the result (appropriately labeled). Run the program to make sure it is correct so far.

2. Now it is time to add the code to do the conversion. The comments in the program guide you through the calculations -- place the appropriate Java statements after each comment.

3. So far the program does not print out the answer. Recall that the answer is the sequence of remainders written in reverse order -- note that this requires concatenating the four digits that have been computed. Since they are each integers, if we just use the + operator the computer will perform arithmetic instead of concatenation. But remember that if either operand to + is a string it will do concatenation, and that in the case of multiple + operations they are performed from left to right. So if you start by concatenating "" (the empty string), it will force the rest of the values to convert to strings -- essentially you are concatenating the values of the four place variables to the empty string. Store the result in the String variable baseBNum already declared and instantiated as an empty string. Print the result appropriately labeled.

4. Run your program. Test it using the following values: Enter 2 for the base and 13 for the base 10 number -- the program should print 1101 as the base 2 value; enter 8 for the base and 1878 for the number -- the program should print 3526 for the base 8 value; enter 3 for the base and 50 for the number -- the program should print 1212.

5. Don't print your program yet! You are going to add something to it later.

### A Program Using If Statements (Conditionals)

The file WaterBill.java contains a program to compute a customer's water and sewer bill. The charge for water is based on consumption -- a customer who uses no more than 7500 gallons in a month pays \$0.002 per gallon but a customer who uses more pays \$0.002 per gallon for the first 7500 gallons plus \$0.0035 per gallon for each gallon over 7500. Note that the charge depends on a condition -- whether or not the amount of water used is over 7500 gallons. Hence an if is needed to compute the charge for the water. Do the following:

1. Save the program to your directory and open it in Eclipse.

2. Study the code and find the if... else... that computes the charge for the water -- there are two different formulas used for the calculation depending on whether numGals is less than or equal to CUTOFF (7500) or not. Also notice near the bottom of the program an if that prints a message for customers who use less than half of 7500.

3. Run the program several times. Enter numbers greater than 7500 (such as 10000), numbers between 7500 and half of 7500 (such as 6000), and numbers less than half of 7500 (such as 3000).

4. First we will add statements to format the dollar amounts using the NumberFormat class (discussed on pages 90 - 92 of the text). Do the following (it will help to look at the example in the text):
1. Add the statement to import java.text.NumberFormat.
2. Declare fmt to be a NumberFormat object and invoke the getCurrencyInstance() method to create a currency formatter object.
3. Use the fmt object with the format method to format the variables waterCharge and totalBill for printing (in the print statements).
4. Run the program to make sure the dollar amounts are now properly formatted.

5. Add an if ... else... to the program to compute the sewer charge. Suppose the charge for sewer services is also based on water usage. A person who uses 7500 gallons or less of water pays \$0.001 for sewer but a person who uses more pays \$7.50 for the first 7500 gallons plus \$0.003 per gallon for each gallon over 7500 (so, for example, a person who used 8500 gallons would pay \$7.50 + \$3.00 = \$10.50). Add appropriate constants to use in your calculations.

6. Update other parts of the program to take the sewer charge into account -- update the calculation of the total bill to include the sewer charge and add a statement to print the sewer charge, properly formatted using the fmt object, in the bill. Run your program to make sure all is correct so far.

7. Suppose senior citizens get a break on the utility tax. The tax rate for senior citizens (those 65 or older) is 8.5% but it is 12% for all others. Add statements to the program to compute the tax. This requires that you find out if the customer is a senior citizen so you need to know their age. You need to do the following:
1. Prompt the user for their age.
2. Write an if to compute the utility tax (note: the tax is paid on the total bill).
3. Add the utility tax to the total bill.
4. Print the utility tax, appropriately formatted, as part of the bill. (NOTE: The total bill should be the last thing printed!)

8. Add an if statement that prints a warning to customers who use more than 3 times the cut off (7500) gallons. Warn them that they are subject to a \$500 fine if their excessive water use continues (just print a message -- don't add the fine to their bill)!

9. Be sure your program works correctly, then print it.

### Adding ifs to the Base Conversion Program

Go back to your base conversion program.
1. Remember that this program only computes 4 digits in the new base so if the user enters a number that is too large to fit in 4 digits the answer produced by the program is incorrect (it is incomplete -- it only gives the rightmost 4 digits). Unfortunately a lot of people believe the computer so we need to be sure the computer doesn't print out incorrect information. So do the following:
1. Replace the statement that prints the answer with an if ... else ... If the number is too large to fit in 4 digits in the new base print a message saying so (remember you calculated the maximum number that will fit); otherwise, print the answer.
2. To test the program, use the following input: 4 for the base and 375 for the base 10 number (the program should say 375 is too big to fit in a 4-digit base 4 number); 7 for the base and 5341 for the number (again, too big); 7 for the base and 537 for the base 10 number (the program should print 1365).

2. Currently the program only works for bases 2 - 9. Our next goal is to expand it to work for bases 2 - 16. The main problem is that we must convert the remainders larger than 9 to the appropriate letter (10 to "A", 11 to "B", ...). Of course the letter must be represented as a char or a String. Modify the program as follows:
1. Change the type of place0, place1, place2, and place3 from int to String.
2. Add a declaration of a variable remainder of type int.
3. Currently to compute the value of place0 you found the remainder when you divided the number by the base. Change your code so that this remainder is stored in the variable remainder (instead of place0).
4. After computing the remainder, we need an if ... else ... to determine the string representation for the remainder to use as place0. Complete the following if ... else ... . Note that it first checks to see if the string representation is the same as the integer.
if ( _______________________________________ )

place0 = "" + remainder;

else if (remainder == 10)

place0 = "A";

else if .....

5. Make the appropriate modifications to find the other place values (you can do some copying of code!).
6. Run the program to make sure it works. Test the numbers you have already tried plus try 16 for the base and 15101 for the number. You should get 3AFD for the answer.
7. Modify the original prompt so it asks for a base in the range 2 - 16.
8. Print a copy of your program.

### Final Exercise: Activities at Lake Lazydays

Implement the Lake Lazydays program from question #9 on pre-lab. That is, write a program that prompts the user for the temperature then prints a message suggesting the appropriate activity. Your program should use a boolean variable for extreme temperatures and a single cascading if statement with conditions as simple as possible (that is, don't have unnecessary comparisons or boolean operators).

Thoroughly test your program. Print it when it is correct.

### Hand In

• The four programs (Age.java, BaseConvert.java, WaterBill.java, and your Lake Lazydays program).
• Tar your directory and email it to your instructor at roanoke.edu with the subject cpsc120 lab5.