It seems to me that you are running into two problems.
The first problem is that although you're using System.nanoTime()
, the clock on your computer and / or operating system should not have enough precision / resolution to measure the time in nanoseconds. Incidentally, as the javadocs of this method show:
This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how often the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis()
.
That translating into Portuguese is:
This method provides nanosecond precision, but not necessarily a nanosecond resolution (that is, how often the value changes) - no guarantee is made except that the resolution will be at least as good as that of currentTimeMillis()
.
The second problem I see is that you make calculations that may lose precision with double
. The double
represents a number with a finite precision, since it occupies only 64 bits, varying the position of the decimal point. This means that small numbers can lose bits of information / accuracy when they are added up with large numbers. For example:
public class Calculo {
public static void main(String[] args) {
double x = 10 * 1e9;
double y = 10 * 1e-9;
System.out.println(x);
System.out.println(x + y);
System.out.println(x == x + y);
double a = 10 * 1e7;
double b = 10 * 1.557e-8;
System.out.println(a + b);
}
}
Here's the output:
1.0E10
1.0E10
true
1.0000000000000015E8
This shows that in this case, the small number ( y
) ended up being totally neglected when it was added to the big number ( x
). This is due to how double
rounds their values so that they fit in their representation. In the case of a + b
, some bits of b
ended up being cut so that they could be summed. So what's happening in your code is that by summing multiple values with many precision decimal (actually binary) decimal places, the least significant bits get discounted so that the value fits within the 64 bits of double
.
Finally, the fact that you're using (double)diff/1000000000.0
causes you to get double rounding problems. It would be best to work with% s of% s representing values in nanoseconds and only convert them in seconds when you show them somewhere.
Furthermore, the fact that your method is long
instead of loop.logics(float delta)
makes me suspect that there must be other places where your program suffers with rounding problems when converting loop.logics(double delta)
(with 64 bits of information ) to double
(with 32 bits of information). Incidentally, was it not for the compiler to give you an error about possible loss of precision when passing float
to a method whose parameter is double
?