Seems to me you’re running into two problems.
The first problem is that although you are using System.nanoTime()
, the clock of your computer and/or operating system shall not have sufficient accuracy/resolution to measure the time in nanoseconds. In fact, as the javadocs of this method show:
This method provides nanosecond Precision, but not necessarily nanosecond Resolution (that is, how Frequently the value changes) - no guarantees are made except that the Resolution is at least as good as that of currentTimeMillis()
.
What translating into Portuguese is:
This method provides an accuracy of nanoseconds, but not necessarily a resolution of nanoseconds (i.e., 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 do calculations that can lose accuracy with the 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 summed 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 way out:
1.0E10
1.0E10
true
1.0000000000000015E8
This shows that in this case, the small number (y
) ended up being totally despised when it was added to the large number (x
). This is due to the way the double
round their values so that they fit in their representation. In the case of the a + b
, some bits of the b
They were cut so that they could be added together. In this way, what is happening in your code is that by adding several values to many decimal places (actually binary ones) of precision, the least significant bits end up being ignored so that the value fits within the 64 bits of the double
.
Finally, the fact that you are using (double)diff/1000000000.0
makes you win the double rounding problems. Best would be to work with long
s representing values in nanoseconds and only convert them in seconds when showing them somewhere.
Also, the fact that your method is loop.logics(float delta)
instead of loop.logics(double delta)
makes me suspect that there must be other places where your program suffers from rounding problems when converting from double
(with 64 bits of information) for float
(32 bits of information). In fact, the compiler was not supposed to give you an error about possible loss of accuracy when passing a double
for a method whose parameter is float
?
In relation to the second problem, the function signature was float, but in the tests I did while writing the question I switched to double, I’m going to change all the parameters to long, so each method converts accordingly, in which case I should be working in milliseconds? since the problem is with the computer.
– ProgramandoMil
You may prefer to use milliseconds, but I see no reason to use Milis instead of nanos.
– Victor Stafusa