Exceptions have types, and what this allows is for you to look up the type and quickly categorize the problem. From the documentation:
ArithmeticException
:
Thrown when an exceptional arithmetic condition has occurred. For example, an integer "divide by zero" throws an instance of this class.
Moreover, most exceptions are constructed with a message to help you even further figure out what happened.
try {
int i = 0 / 0;
} catch (ArithmeticException e) {
e.printStackTrace();
}
This prints:
java.lang.ArithmeticException: / by zero
at [filename:line number]
But how did this happen?
Java, like many other programming languages, distinguishes between integer division and floating point division.
The binary /
operator performs division, producing the quotient of its operands. The left-hand operand is the dividend and the right-hand operand is the divisor. Integer division rounds toward 0. [...] if the value of the divisor in an integer division is 0, then an ArithmeticException
is thrown.
The following may surprise you if you're not familiar with integer division:
System.out.println(1/2); // prints "0"
What happens here is that since both the dividend and the divisor are int
, the operation is an integer division, whose result is rounded to an int
. Remember that an int
can only contain whole number (of limited range, some 4 billion numbers approximately).
You can specify that you need a floating point division by making at least one of the operands a floating point number.
System.out.println(1/2.0); // prints "0.5"
System.out.println(1D/2); // prints "0.5"
D
is a special suffix for numeric literal to specify that it's a double
-precision value. There's also L
for long
(64-bit integer).
A double
value needs to be stored in a double
variable.
double v = 1D / 2; // v == 0.5
int i = 1D / 2; // DOESN'T COMPILE!!! Explicit cast needed!
Note that which division is performed doesn't have anything to do with what type it'll eventually go to. It only depends on what type the dividend and divisor are.
double v = 1 / 2; // v == 0.0 (!!!)
You should also note that double
too, is a limited precision number.
System.out.println(.2D + .7D - .9D); // prints "-1.1102230246251565E-16"
But what about my code?
So now, let's focus on what happened with your code:
timeTaken = stopTime - startTime;
timeInSecs = ((timeTaken/1000));
speed = 45/timeInSecs;
More than likely what happened is that timeTaken
is declared as a long
. Therefore timeTaken/1000
results in integer division. If timeTaken < 1000
, the result of the division is 0
.
At this point, it doesn't matter if timeInSecs
is a double
or a float
, because the integer division has already been performed. This means that timeInSecs
would be either 0
or 0.0
, depending on its type.
From the error you get, though, one can determine that timeInSecs
is likely to be an integer type. Otherwise, 45/timeInSecs
would result in a floating point division that results in Infinity
(a special double
value) instead of throwing ArithmeticException
.
So how do we fix this?
We can fix this by declaring the variables as follows:
long timeTaken;
double timeInSecs;
double speed;
And then performing the calculation as follows (note that 1000
is now a double
value).
timeTaken = stopTime - startTime;
timeInSecs = timeTaken/1000D;
speed = 45D/timeInSecs; // D is not necessary here, but it's good for clarity
See also