user6226929 user6226929 - 2 months ago 7
Java Question

Is there a way to represent variables as int instead of double to calculate correct percentage?

I am doing exercise 2.3 on page 23 of Think Java (http://www.greenteapress.com/thinkapjava/thinkapjava.pdf).

The program converts an arbitrary time stored in variables to seconds, then calculates the amount of seconds remaining in the day, then how much of the day has elapsed in percentage.

Here's the working program:

public class Time {

public static void main(String[] args) {

double hour = 21.0; //Represents 9 PM
double minute = 5.0; //Represents 9:05 PM
double second = 33.0; //Represents 9:05:33 PM

final double SEC_IN_MIN = 60.0; //Made final because the amount of seconds in a minute does not change
final double SEC_IN_HOUR = 3600.0; //Made final for the same reason above.

final double SEC_SINCE_MN = (SEC_IN_HOUR * hour) + (SEC_IN_MIN * minute) + second; //Calculates the seconds since midnight, or 00:00
final double SEC_IN_DAY = 24.0 * SEC_IN_HOUR; //Calculates the amount of seconds in a day; 24 stands for the hours in a day

System.out.printf("The number of seconds since midnight is: %.0f\n", SEC_SINCE_MN);
System.out.printf("The number of seconds remaining in the day is: %.0f\n", SEC_IN_DAY - SEC_SINCE_MN);
System.out.printf("The percentage of the day that has passed is: %.0f%%", (100 * SEC_SINCE_MN) / SEC_IN_DAY); // Escape percent sign is %% 100 * to remove decimal value

}


}

I know there is a better way with more advanced code but this is what the assignment required based on what we have learned so far. However, I am not sure double is the best way to represent the variables as I have to use a format specifier to trim the decimal. I asked my professor about it and he said I could change all the variables to int and change the computation in the last print statement to:

System.out.printf("The percentage of the day that has passed is: %d%%", (100 * SEC_SINCE_MN) * 1.0 / SEC_IN_DAY);


This does not work because I get a d != java.lang.Double error for the last print statement. If I change the 1.0 to 1, I get no errors put the last output is incorrect.

It says 87% instead of 88% which is the correct output because the decimal value for the last print statement output is 0.08788.

I think it's my computation that needs to be changed for it to work with int.

Any ideas on how to edit the program for int instead of double?

EDIT: Code that doesn't work as per my professor's suggestions (returns java.lang.double error for last print statement)

public class Time {

public static void main(String[] args) {

int hour = 21; //Represents 9 PM
int minute = 5; //Represents 9:05 PM
int second = 33; //Represents 9:05:33 PM

final int SEC_IN_MIN = 60; //Made final because the amount of seconds in a minute does not change
final int SEC_IN_HOUR = 3600; //Made final for the same reason above.

final int SEC_SINCE_MN = (SEC_IN_HOUR * hour) + (SEC_IN_MIN * minute) + second; //Calculates the seconds since midnight, or 00:00
final int SEC_IN_DAY = 24 * SEC_IN_HOUR; //Calculates the amount of seconds in a day; 24 stands for the hours in a day

System.out.printf("The number of seconds since midnight is: %d\n", SEC_SINCE_MN);
System.out.printf("The number of seconds remaining in the day is: %d\n", SEC_IN_DAY - SEC_SINCE_MN);
System.out.printf("The percentage of the day that has passed is: %d%%", (100 * SEC_SINCE_MN) * 1.0 / SEC_IN_DAY); // Escape percent sign is %%. 100 * to remove decimal value

}


}

EDIT: Code that works but doesn't give the correct output of 88% for the last print statement

public class Time {

public static void main(String[] args) {

int hour = 21; //Represents 9 PM
int minute = 5; //Represents 9:05 PM
int second = 33; //Represents 9:05:33 PM

final int SEC_IN_MIN = 60; //Made final because the amount of seconds in a minute does not change
final int SEC_IN_HOUR = 3600; //Made final for the same reason above.

final int SEC_SINCE_MN = (SEC_IN_HOUR * hour) + (SEC_IN_MIN * minute) + second; //Calculates the seconds since midnight, or 00:00
final int SEC_IN_DAY = 24 * SEC_IN_HOUR; //Calculates the amount of seconds in a day; 24 stands for the hours in a day

System.out.printf("The number of seconds since midnight is: %d\n", SEC_SINCE_MN);
System.out.printf("The number of seconds remaining in the day is: %d\n", SEC_IN_DAY - SEC_SINCE_MN);
System.out.printf("The percentage of the day that has passed is: %d%%", (100 * SEC_SINCE_MN) / SEC_IN_DAY); // Escape percent sign is %%. 100 * to remove decimal value

}


}

Answer
(100 * SEC_SINCE_MN) / SEC_IN_DAY

is multiplying the integer SEC_SINCE_MN by the integer 100, and then divides it by the integer SEC_IN_DAY. So that's an integer division. It just truncates the decimal part of the result.

What you want is to compute the accurate percentage, with the decimals, and then round the result. So you need a floating point division:

(100.0 * SEC_SINCE_MN) / SEC_IN_DAY

That will produce a double value (87.88541666666667), that you then need to round:

Math.round((100.0 * SEC_SINCE_MN) / SEC_IN_DAY)