我已经阅读了System.nanoTime()
的javadoc,这一切看起来都很清楚。直到我到达最后一段:
比较两个nanoTime值
long t0 = System.nanoTime();
...
long t1 = System.nanoTime();
应该使用t1-t0< 0,不是t1< t0,因为数字溢出的可能性。
有两件事我不清楚:
t1 < t0
之后t1
被t0
检查,为什么会检查t1 > t0
?我的理解是纳米时间总是在增加。所以,我宁愿检查t1 - t0 > 0
。t1 > t0
。我仍然不知道为什么这是正确的检查方式而不是angulartics-google-analytics.min.js
。他们提到数字溢出,我不太明白他们的意思。关于数值溢出,这里提到的是:跨越大于约292年(2 ^ 63纳秒)的连续调用的差异将无法正确计算由于数值溢出而导致的经过时间。
好的,因为纳米时间存储为长值,它最终会在292年内溢出。接下来会发生什么?它是从头开始,即最低负值-2 ^ 63?或者它是否会停止测量并返回(2 ^ 63 - 1)?
答案 0 :(得分:9)
你是对的,你引用的文档部分似乎有点混乱。
但是,重要的文档部分是:
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示纳秒,因为某些固定但任意的原始时间(可能在将来,因此值可能为负)。在Java虚拟机的实例中,此方法的所有调用都使用相同的原点;其他虚拟机实例可能使用不同的来源。
(强调我加上。)
这意味着您无法保证在产生的长值将从正变为负值时,您的代码不会正常运行。
没有什么可以保证这将在300年后发生,今天可能会发生。
目前,我的JVM返回了一些像3496793269188这样的数字,但是如果它想要的话,它可以返回一些非常接近9223372036854775807的数字(Long.MAX_VALUE
),这将从正到负翻转迫在眉睫。
所以,你应该采取一切必要的预防措施。
答案 1 :(得分:7)
嗯,javadoc
说实话。考虑这样的例子:
long t0 = Long.MAX_VALUE;
long t1 = Long.MIN_VALUE;
System.out.println(t1 < t0);
System.out.println(t1 - t0 < 0);
它会给出
true
false
虽然在数学上两个表达式都是真的。但在我们的情况下,我们知道,time
的负值意味着它溢出,因此它应该是更大然后是正数。
答案 2 :(得分:2)
让我从问题的结尾开始。是的,如果值大于2 ^ 63-1,则值将溢出。溢出的常见实现是存储结果的最不重要的可表示位;值将换行(你可以在我的帖子底部看到溢出以供参考)
序列如:2^63-2, 2^63-1, -2^63, -(2^63-1) ...
现在回顾Javadoc我同意关于使用比较的解释令人困惑,我们自然会尝试比较t1 > t0
以验证t1
之后t0
是否发生。 你是部分正确的。虽然我不认为这是一个拼写错误,但没有正确解释。我认为应该说:
对于两个值
t0
和t1
(在t0之后捕获t1),您不应使用t1 < t0
(检查false
)而是使用{{1同样,你不应该使用t1 - t0 < 0
(检查t1 > t0
)而是true
或者将其正式化:
对于两个'纳米'值
t1 - t0 > 0
和t0
,在t1
次展位后t1
被捕获:t0
只要(t1 - t0 > 0) == true
和t1
之间的时间段<= 2 ^ 63 ns。
为什么?因为即使t0
溢出(因此它是负数),结果t1
也将是负但是,它将小于-2 ^ 64并且它将“溢出”回到正值价值!。
只要满足t1 - t0
和t0
之间距离的条件,就会有效!如果距离大于2 ^ 64,例如:对于t1
,减法结果将为:t0 = 1; t1 = -(2^64-2)
因此指定的条件(t1 - t0 = -(2^64-1)
)将给出不正确的结果。
右:?)
为了便于解释,lats假定使用8位存储的类型(而不是长度使用的64位),所以二进制到十进制表示为:
t1 - t0 > 0
现在下一个数字自然会增加1。 将1加到二进制1111 1111将产生1 0000 0000
0000 0000 => 0
0000 0001 => 1 (2^0)
0000 0010 => 2 (2^1 + 2^0)
...
1111 1111 => 255 (2^7 + 2^6 + ... + 2^1)
通常位置8上的溢出位将代表(负权重)符号位
(1) 0000 0000 => -256 !!!
你得到了照片
这源于底层硬件注册表实现,它依赖于二进制值。 您可以在此处阅读更详细的说明:http://www.allaboutcircuits.com/textbook/digital/chpt-2/binary-overflow/
答案 3 :(得分:2)
当t1在t0之后(t1 如果读取无符号数字,则更基本的负数会大于带符号的正数:https://en.wikipedia.org/wiki/Signed_number_representations和