Whats the difference in these two ways to convert milliseconds to seconds?

944 views Asked by At

First way:

   long mySeconds = milliseconds/ 1000;

Second way:

   double mySeconds = milliseconds * 1e-3d;

This calculation is finally used to determine index of an array, like this:

  int index = (int) ((someDoubleSeconds + mySeconds)/ someDouble);

What difference would the two approaches make?

Also does the first approach rounds to the next second or truncates like floor function?

2

There are 2 answers

0
dcsohl On BEST ANSWER

As others have pointed out, the first way truncates (rounds down, effectively, in this case) and the second way does not. So if milliseconds is 10999 then the first way gets you 10 and the second gets you 10.999.

What difference this makes in the third line? Well, consider if someDoubleSeconds = 0 and someDouble = 10.5. Then if milliseconds is 10999, your mySeconds could be 10 or could be 10.999, and the result of the third line could be 0 or it could be 1. (since 10/10.5 is less than one, and would be truncated to 0 by the cast to int, and 10.999/10.5 is greater than one, and would be truncated to 1 by the cast to int)

1
krems On

The fisrt one is an integer division, which means that for example if you had

long mySeconds = 1234

after division by 1000 you'll get 1.

The second way will give you an accurate double, which I don't think you want. Will a second and a half fit you?

The third way is a bit complcated due to double rounding to integer. See java lang specification:

A narrowing conversion of a floating-point number to an integral type T takes two steps:

1) In the first step, the floating-point number is converted either to a long, if T is long, or to an int, if T is byte, short, char, or int, as follows:

. If the floating-point number is NaN (§4.2.3), the result of the first step of the conversion is an int or long 0.

. Otherwise, if the floating-point number is not an infinity, the floating-point value is rounded to an integer value V, rounding toward zero using IEEE 754 round-toward-zero mode (§4.2.3).

Then there are two cases:

. If T is long, and this integer value can be represented as a long, then the result of the first step is the long value V.

. Otherwise, if this integer value can be represented as an int, then the result of the first step is the int value V.

. Otherwise, one of the following two cases must be true:

. The value must be too small (a negative value of large magnitude or negative infinity), and the result of the first step is the smallest representable value of type int or long.

. The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or long.

2) In the second step:

. If T is int or long, the result of the conversion is the result of the first step.

. If T is byte, char, or short, the result of the conversion is the result of a narrowing conversion to type T (§5.1.3) of the result of the first step.

BTW There is a good way to convert time units in Java standart library: java.util.concurrent.TimeUnit.